时间节点 线程 A(先到请求) 线程 B(并发请求) 线程 C(后续请求) 关键行为与结果
0s 拿到锁,开始执行业务代码 未拿到锁,等待 A 执行完成 - 只有 A 进入「查库 + 写缓存」流程,避免多线程同时打数据库
1s 查询数据库 继续等待 - A 从 MySQL 读取数据
1.5s 执行完业务代码,写入 Redis 缓存 继续等待 - 数据成功写入 Redis,缓存被填充
2s 释放锁 拿到锁,执行业务代码 - B 尝试查缓存,发现已存在,直接返回缓存数据
3s 已执行完成,缓存已有数据 已执行完成 执行业务代码,发现缓存已存在,直接返回 C 完全走缓存,不再访问数据库

后台缓存优化

1.本地缓存

本地缓存(一级) → Redis(二级) → DB

纯 Map 做不到自动清理!因为它没有:

  • 过期时间
  • 最大容量限制
  • LRU 淘汰(最少使用删除)
  • 并发安全控制

所以必须用框架

2.gava缓存

com.tuling.tulingmall.component.LocalCache

1、设置最大容量 2、初始化容量 3、缓存过期
多少层缓存???两层 本地缓存 redis缓存

  • 本地缓存(Guava/Caffeine) → 速度最快
  • Redis 分布式缓存 → 全局一致
  • DB(最后兜底)

你课上所有问题 → 直接给标准答案
1)分布式下,本地缓存、Redis、DB 如何保持伪实时同步?
答案:
Canal 监听 MySQL binlog → 实时更新 Redis → 本地缓存设置短过期(自动更新)
2)多个接口(商品、订单)需要多个布隆过滤器吗?
不需要!
存在 Redis,不同前缀区分即可,不需要多个过滤器。
3)4 核 8G 机器并发多少合适?
200~500 QPS 正常
超过 1000 开始压力大
超过 2000 必须优化
4)单个服务 400/s 高还是低?
不高,属于正常偏低
一般企业接口:
低:100~300
中:300~800
高:800~3000+
5)优化策略?
加本地缓存
加 Redis
加布隆过滤器
加分布式锁
分库分表
读写分离
6)tryLock 原理是什么?
CAS 无锁竞争
底层是:
Redis SETNX 命令(互斥写入)
只有一个线程能成功写入锁,其他失败。
7)启动 OrderApplication 报 protocol=http host=null
是 Nacos/Feign 配置问题,知识星球能解决。
8)1000 万商品会造成 Redis BigKey 吗?
不会!
布隆过滤器底层是 bitmap,极小内存。
1000 万只占几 MB,完全没问题。
9)Guava 本地缓存分布式环境能用吗?
能用!
但每个机器本地缓存是独立的,所以叫:
本地缓存 + Redis 最终一致性
适合高并发读。
 

终极方案

如果后台数据有变更呢?如何及时同步到其它服务端? 页面在不通服务间如何同步
如果页面静态化了,我们搜索打开一个商品详细页,怎么知道要我需要的访问的静态页面?
万一我们模板需要修改了怎么办?
牵一发动全身。

Nginx + OpenResty + Lua 完全可以当后端用,而且是高性能后端

数据热点:
3层缓存:
lua+nginx:数据里小、访问量相对来很高
jvm本地缓存:数据里很大、访问量相对来高
redis:数据里相对来说比较大、访问量相对来不高

京东方案

1.0

IIS+C#+Sql Server,最原始的架构,直接调用商品库获取相应的数据,扛不住时加了一
层memcached来缓存数据。这种方式经常受到依赖的服务不稳定而导致的性能抖动。
备注:加入了缓存,但是问题受限于缓存服务器,不稳定

架构2.0:

该方案使用了静态化技术,按照商品维度生成静态化HTML。主要思路:
1、通过MQ得到变更通知;
2、通过Java Worker调用多个依赖系统生成详情页HTML;
3、通过rsync同步到其他机器;
4、通过Nginx直接输出静态页;
5、接入层负责负载均衡。
备注:该方案的主要缺点:
1、假设只有分类、模板变更了,那么所有相关的商品都要重刷;
2、随着商品数量的增加,rsync会成为瓶颈;
3、无法迅速响应一些页面需求变更,大部分都是通过JavaScript动态改页面元素。
随着商品数量的增加这种架构的存储容量到达了瓶颈,而且按照商品维度生成整个页面会
存在如分类维度变更就要全部刷一遍这个分类下所有信息的问题,因此我们又改造了一版
按照尾号路由到多台机器。

3.0

主要思路:
1、容量问题通过按照商品尾号做路由分散到多台机器,按照自营商品单独一台,第三方
商品按照尾号分散到11台;
2、按维度生成HTML片段(框架、商品介绍、规格参数、面包屑、相关分类、店铺信
息),而不是一个大HTML;
3、通过Nginx SSI合并片段输出;
4、接入层负责负载均衡;
5、多机房部署也无法通过rsync同步,而是使用部署多套相同的架构来实现。

该方案主要缺点:
1、碎片文件太多,导致无法rsync;
2、机械盘做SSI合并时,高并发时性能差,此时我们还没有尝试使用SSD;
3、模板如果要变更,数亿商品需要数天才能刷完;
4、到达容量瓶颈时,我们会删除一部分静态化商品,然后通过动态渲染输出,动态渲染
系统在高峰时会导致依赖系统压力大,抗不住;
5、还是无法迅速响应一些业务需求。

1、之前架构的问题存在容量问题,很快就会出现无法全量静态化,还是需要动态渲染;
不过对于全量静态化可以通过分布式文件系统解决该问题,这种方案没有尝试;
2、最主要的问题是随着业务的发展,无法满足迅速变化、还有一些变态的需求。

4.0

1、能迅速响瞬变的需求,和各种变态需求;
2、支持各种垂直化页面改版;
3、页面模块化;
4、AB测试;
5、高性能、水平扩容;
6、多机房多活、异地多活。

主要思路:
1、数据变更还是通过MQ通知;
2、数据异构Worker得到通知,然后按照一些维度进行数据存储,存储到数据异构JIMDB
集群(JIMDB:Redis+持久化引擎),存储的数据都是未加工的原子化数据,如商品基
本信息、商品扩展属性、商品其他一些相关信息、商品规格参数、分类、商家信息等;
3、数据异构Worker存储成功后,会发送一个MQ给数据同步Worker,数据同步Worker
也可以叫做数据聚合Worker,按照相应的维度聚合数据存储到相应的JIMDB集群;三个
维度:基本信息(基本信息+扩展属性等的一个聚合)、商品介绍(PC版、移动版)、其
他信息(分类、商家等维度,数据量小,直接Redis存储);
4、前端展示分为两个:商品详情页和商品介绍,使用Nginx+Lua技术获取数据并渲染模
板输出。
另外我们目前架构的目标不仅仅是为商品详情页提供数据,只要是Key-Value获取的而非
关系的我们都可以提供服务,我们叫做动态服务系统。

该动态服务分为前端和后端,即公网还是内网,如目前该动态服务为列表页、商品对比、
微信单品页、总代等提供相应的数据来满足和支持其业务。

    nginx对比tomcat

    # 为什么 Nginx 比 Tomcat 快?核心底层原理,通俗讲透
    ## 一、核心本质差异
    1. **Nginx**:**事件驱动、异步非阻塞、单进程多事件**
    2. **Tomcat**:**线程模型、同步阻塞、一个请求占一个线程**

    ---
    ## 二、5个关键原因(直白好懂)
    ### 1. 网络模型完全不一样
    - **Nginx**:Epoll/Kqueue 多路复用
      一个工作进程,**可以同时监听成千上万个连接**,哪个连接有数据就处理哪个,空闲不卡、不浪费资源。
    - **Tomcat**:BIO/NIO 线程池
      来一个请求,**开/占一个线程**;1000个请求就要几百上千个线程。
      线程多了就:**内存暴涨、CPU 频繁切换上下文、卡死**。

    ### 2. 处理逻辑轻重不一样
    - **Nginx**:只做转发、静态文件、Lua 轻量逻辑,**极简、无多余开销**。
    - **Tomcat**:跑 Java 虚拟机、加载 Spring 容器、反射、依赖注入、业务上下文,**本身就很重**。

    ### 3. 阻塞等待方式不同
    - Nginx:**非阻塞**
      连Redis、读文件、等后端响应时,**不卡死进程**,转头去处理别的请求。
    - Tomcat:**同步阻塞**
      线程在等数据库/接口返回时,**线程原地卡死闲着**,白白占资源。

    ### 4. 进程/线程开销差距大
    - Nginx 就开几个**工作进程**就能扛 **10万+ 并发**。
    - Tomcat 并发一高,线程池拉满,**线程切换开销远大于业务处理开销**。

    ### 5. 定位不一样
    - Nginx:天生为**高并发、高吞吐、静态资源、网关**设计。
    - Tomcat:天生为**运行 Java Web 业务、复杂业务逻辑**设计,不是为了扛超大并发。

    ---
    ## 三、举个通俗例子
    - **Nginx** 像**一个超级前台**:
      一个人同时接待1000个客人,谁有事就招呼谁,没人等就空闲,效率拉满。
    - **Tomcat** 像**雇了100个服务员**:
      来一个客人分配一个服务员,客人坐着等菜时,服务员也得站着等,不能去接待别人,人多就乱套。

    ---
    ## 四、结合你之前的业务
    商品详情页这种**读多写少、高并发**场景:
    用 **OpenResty(Nginx+Lua) 直接当后端**
    避开 Tomcat/JAVA 厚重链路,
    **Nginx 直接在网关层就把页面渲染、缓存、查Redis干完**,速度碾压走 Tomcat 链路。

    ---
    ## 五、一句话总结
    Nginx 快在:**异步非阻塞 + 多路复用 + 轻量极简**
    Tomcat 慢在:**同步线程模型 + JVM 重容器 + 阻塞等待**。

    需要我给你画一张「Nginx事件模型 vs Tomcat线程模型」简易对比图,方便你做汇报吗?

    Logo

    AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

    更多推荐