21天技术人写作行动训练营-Day03输出有价值的内容
输出有价值的内容

打卡内容
- 写一篇文章,记录自己最近一次解决工作中难点的经历,不少于500字,
- 加练挑战:选择一讲对你有帮助极客时间专栏课程,写一些这节课好在哪里,字数不限。
服务宕机引发对做系统限流的思考
问题背景
最近遇到了这样一个问题。用户想做新版本验证,于是准备了两套环境,EnvA环境应用部署老代码,日常有流量打过来并稳定运行,EnvB环境应用部署新版本,日常无流量打过来为测试环境。
正常流程如下:管控端管理测试场景,并通过配置中心将测试场景信息下发到EnvA的各个机器上;App1,App2,App3接收到后,当有与测试场景相关的流量,就会复制一份路由到EnvB的测试机器App4。数据采集端收集两个环境相同流量的运行结果,并上报给管控端,管控端比较相同流量在EnvA和EnvB机器上的响应,从而验证新版本是否有问题。
问题现场:当EnvA的日常流量过多时,EnvB的单机短时间流量压力过高,导致机器负载飙升,最后App4机器直接被流量打挂。

问题分析
设计方案时,未考虑EnvA环境某些测试场景流量tps过高的场景,让EnvB环境用单机去接收EnvA环境整个集群的流量,就会出现以上问题。所以在做流量复制转发时,需要考虑做限流措施保障EnvB环境测试机器的稳定性。
解决方案
方案一:
配置中心做限流,在推送测试场景时,选择少量EnvA环境的机器去推送,从而只让部分机器做流量转发,从流量源上做限流。如下图所示,从EnvA中选择一台机器推送测试场景做流量复制路由。

缺点分析:
- EnvA集群的场景流量分布对配置中心而言是黑盒的。对于某个测试场景,配置中心并不知道EnvA中哪台机器会有流量,如果选择一台无流量的机器推送测试场景,就会导致EnvB机器也无流量,也就无法做测试验证。(比如某个测试场景流量只发生在App2机器,那么配置中心将该场景测试信息推送到App1机器,就无法做测试验证)
方案二:
EnvB部署更多机器,EnA中每台机器接收到流量后,做负载均衡将流量均匀分发到EnvB的每台机器上,从而将EnvA集群的流量压力均摊到了EnvB的每台机器上。这里负载均衡的策略有很多,比如轮询、随机分发等多种方式。举个🌰:一笔流量打到App1后,App1按轮询的方式,将这笔流量转发给App4,当有下一笔流量来时,则转发给App5。

缺点分析:
- 用户不知道该在EnvB中部署多少机器才能支撑EnvA集群的流量压力
- 当应用EnvA中集群机器数过多时,那么EnvB就需要投入更多机器资源,就测试而言,成本过高。
方案三:
在EnvA中做限流,设定一个策略决定EnvA中机器接收到流量后是否转发这笔流量。
举个🌰:如上图假设现在EnvA中有三台机器,EnvB中有两台机器,那么可以设置EnvA中每台机器转发流量的策略为:当App1来了一笔流量后,以2/3的概率将该笔流量转发出去,转发至EnvB的哪台机器,则可以用负载均衡的方式选择EnvB中的哪台机器。这里EnvA中流量转发概率: sendRate = EnvB机器数/EnvA机器数(也可以设计更复杂准确的策略,这里举个最简单的方式),这样就能保证EnvB中每台机器承受的负载压力,大致与EnvA中每台机器承受的负载压力相同。
总结
- 解决问题的思路:从最开始在流量源上做限流 -> 在接收端做负载均衡,分摊压力 -> 综合两种方案,在流量源和接收端都做处理,从而达到限流的目的,最终为用户解决问题。
- 好的方案都是通过不断探索思考,优化总结得出的。
浙公网安备 33010602011771号