1. 本次的问题:
a) 首要问题: 缓存时间与机制的问题导致系统持续性雪崩
- 缓存时间——10s : 缓存时间太小
- 当这个缓存还没抗住所有的流量,就过期了,需要建立新的cache
- 预缓存—— 预缓存? 没有预缓存这个内容
- 解释: 在大流量下,如果某个缓存过期了,是否能提前建立好新内容的缓存—— 防止雪崩
b) 次要问题:
- Nuxt 的缓存页面数量:100个,太少了
- 多加一点 ,按照每个实例缓存 1.5G的内存来设置此值;(经过计算大概在5000 左右)
- 防止高流量下 cache 建立好了之后,被立即淘汰了
- Nuxt 请求后端的api 的timeout时间:20s太长了
- 目前 设置时间20s,它会拉长缓存失效时刻起,到缓存建立成功这个空白时间—— 会有更多的流量会打到数据库——会导致php 负载更高 —— api 的请求 response 时间更长——导致了恶性循环
- 如果设置1s ,时间太短:容易造成无法建立缓存,
- 建议时间 5s;
- Nuxt 的缓存是根据 用户的 id 相关,所以同一个用户多次访问必须负载到同一个实例——(IP HASH 规则)
2. 解决方案,以及验证结果展示
2.1 缓存时间与机制的问题导致系统持续性雪崩 —— 解决方案:
修改 /nuxt.config.js 文件如下
1、设置EXPISE = 30s,每个key 缓存 150s ,每过30s 后 ,最后的key 中的time 会 +1 ;
2、绝大多数 request 请求都会打到 time 上面 : (用这个方法防止雪崩)
a) 1/50 的流量会提前 建立 time+1 这个key;
b) 1/100 的流量会提前 建立 time+2 这个key;
c) 1/200 的流量会提前 建立 time+3、time+4、time+5、 这个key;
3、如果登录的用户非常的多? 上面的游客缓存的机制会被绕过?(特别注意)
a) 加大缓存时间、服务器资源:
- 因为登录用户,每个人肯定要访问一次数据库(每个人看到的页面都不同),所以必须实时渲染
- 尽可能 一次 会话中,只访问一次数据库
- 这是个缓慢增涨的过程
b) 缓存组件(编码层面)
4、如果还扛不住 ? 那必须在前面再加一个go 或者node ,做一次 io cache 中间件。(特别注意)
2.1.1 关于雪崩问题,优化前的性能测试
压测 60s
设置的变量 | 并发 | QPS | 响应时长 | 错误率 | cpu(nuxt) | cpu(php) |
并发为50 | 50 | 113 | 441ms | 0 | 满负荷 | 0%-30% |
并发为100 | 100 | 19 | 4852ms | 0 | 满负荷 | 30%-50% |
并发为200 | 200 | 11 | 15827ms | 0 | 满负荷 | 30%-50% |
qps为50 | 10 | 45 | 45ms | 0 | 40%-60% | 0%-7% |
1.我们可以发现当并发为100的时候 ,qps 急速的下降, 开始雪崩
a) 通过监控可以看到,会不断的往后端php 发送大量api请求。cache没有搂住
2.1.2 关于雪崩问题,优化后的性能测试
压测100s (并发 从 0 - n ,需要30s 建立)
设置的变量 | 并发 | QPS | 响应时长 | 错误率 | cpu(nuxt) | cpu(php) |
并发为50 | 50 | 250 | 150ms | 0 | 满负荷 | 0% |
并发为100 | 100 | 247 | 342ms | 0 | 满负荷 | 3% |
并发为200 | 200 | 241 | 696ms | 0 | 满负荷 | 3% |
qps为100 | 20 | 84 | 29ms | 0 | 40%-50% | 0% |
- 优化之后 ,在高并发下 ,qps 翻了20多倍;而且 非常的稳定运行
- 按照8个实例来说,按照最差的场景 80的qps 增加到 1900 qps;
- 后端基本没有任何雪崩迹象
2.2 次要问题解决:
2.2.1 Nuxt 的缓存页面数量:100个,太少了?——解决方案
这个需要根据实际的部署情况来定(控制每个实例的内存消耗在 1-1.5Gz左右)—— 经过计算大概在5000 左右
2.2.2 同一个用户访问 负载均衡到同一个实例?——解决方案
> 目前问题: 同一个用户可能在多个实例中有重复的缓存,导致了资源巨大浪费
解决方案:按照目前的拓扑方案——无法解决
(pm2 手册翻完了 ,也没有看到关于 负载均衡策略的配置;)
警告:如果后续存在 内存占满了,而且后端php 和 nuxt 的cpu 持续不下降,就是它的问题;