K8S容器云高可用场景TPS下降明显
高可用场景优化:容器云三台物理机,其中一台重启,TPS下降到几乎为0,且TPS恢复时间需要60S
背景
K8S,配置了反亲和
springcloud 微服务
两地三中心部署
应用单机房3台物理机NODE(128C 512G),其中2台物理机能承载目前测试TPS要求
交易涉及4个微服务(GW、加密服务、全局路由服务、BUS),每个微服务pod数是3的倍数
http请求中间件:OkHttp3(connectTimeout =30S,readTimeout=60S)
现象
非功能测试,高可用场景,单机房一个NODE重启
预期结果:200并发应用1000TPS,重启期间内,所有微服务1/3的POD异常,有部分(50%+)交易失败,TPS有短暂下降,即到300左右TPS,60S内TPS恢复。
实际效果:重启期间,TPS最低点下降为几乎为0,在60S的时间,TPS逐渐恢复。
问题分析
下图是简易的交易流程图
阻塞原因
交易进入云内(从GW开始),每个节点都有1/3的失败或是超时概率,超时的最终结果也是失败。
我们梳理一下出现connectTimeout的位置:
- ingress ->GW
- GW -> 加密服务 解密
- GW -> 全局路由服务
- GW -> BUS(业务单元)
- GW -> 加密服务 加密
所以一笔交易成功的概率是 2/3 的5次方,即为32/243 ≈ 13%
TPS恢复时间60S,这么长;
每条链路都会超时,而且connectTimeout时间不统一,有的是30S,有的是5S,而且链路中有调用失败的异常处理逻辑。
TPS会下降到0
按照如上论证,成功率应该是13%,即:1000TPS*13%=130TPS。
- ESB有并发限制(如100,图上画的是50);
- Jmeter这样的测试工具,200线程并发的测试原理是,一次发200的request,等response后,再发request,保证同时有200个request。即如果这200个request夯住了,新的请求没法进来。
- 真实的业务不是这样的。真实的业务是有10W个在线用户,ESB有100的并发,应用响应时间100ms,TPS就是(100并发/100ms)1000。即如果有100个线程阻塞了,其他用户会继续发送交易,ESB的实时并发数会涨起来,100 < 实时并发数 <= 200。
解决方案
- ESB的并发限制调大,如调成200(至少是实时并发数的2倍)
- 修改各个请求节点的connectTimeout时间,改成1S。
注意不要修改成了readTimeout或是responseTimeout - 修改测试方法1;并发数修改为1000,交易间隔1000ms,让应用TPS一样是1000,ESB线程数仍是100左右。压力机压一段时间后(让交易均匀分布到每秒钟),然后重启NODE。
- 修改测试方法2;我们要验证的是出现故障的情况,交易能持续进来,虽然有部分成功,但是不会造成阻塞;我们需要另外一台压力机,如并发数200,交易间隔100ms,Jmeter的responseTimeout为100ms(一般等于交易ART)。即Jmeter不等交易返回,不阻塞,持续发压力,验证系统能持续处理请求,并且预期TPS会提升。
- 修改测试方法3;修改Jmeter的TPS采样间隔,默认是1S,可以修改大一点,如2S。这样测试曲线图好看一些。
本次验证未修改。
后续
发现最低点TPS果然不是0了,但是不是130,只有16左右。
原因分析
在出现宕机的时候,ESB的实时并发数是100,即有100个请求同时到业务系统,这里只有100*(32/243)=13能成功,其余交易或是报错或是要等待connectTimeout,在这一秒无法response的,但是jmeter是按照每1秒统计TPS的,所以最低点是ESB的实时并发线程数 * 13%(阻塞时,ESB实时线程数会大于100),而不是原TPS * 13%。
修改connectTimeout要<=Jmeter统计间隔,否则不会提高TPS的最低点,只是让系统尽快恢复到原TPS。因为Jmeter统计时间1S(当然可以调大),connectTimeout大于1S,就会统计时间内有阻塞。connectTimeout=1S成功率为13%;connectTimeout=2S,第2秒的成功率就是0.13 * 0.13=0.02;connectTimeout=3S,第3秒的TPS就接近0了。
快速恢复的原因:异常链接快速失败了,所以在5S内交易都能恢复到1000TPS,而不是60S了。
注意
宕机的场景是,IP对应的机器不存在,即IP ping不通,如果IP能ping,即端口不可用,是不会触发connectTimeout,是可以快速返回调用端失败的。
简单的验证方式就是:
telnet 不存在的ip(10.101.101.99) 8080;
发现会在差不多20S超时
参考
更多推荐
所有评论(0)