K8S容器云高可用场景TPS下降明显

背景

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的位置:

  1. ingress ->GW
  2. GW -> 加密服务 解密
  3. GW -> 全局路由服务
  4. GW -> BUS(业务单元)
  5. GW -> 加密服务 加密
    所以一笔交易成功的概率是 2/3 的5次方,即为32/243 ≈ 13%

TPS恢复时间60S,这么长;

每条链路都会超时,而且connectTimeout时间不统一,有的是30S,有的是5S,而且链路中有调用失败的异常处理逻辑。

TPS会下降到0

按照如上论证,成功率应该是13%,即:1000TPS*13%=130TPS。

  1. ESB有并发限制(如100,图上画的是50);
  2. Jmeter这样的测试工具,200线程并发的测试原理是,一次发200的request,等response后,再发request,保证同时有200个request。即如果这200个request夯住了,新的请求没法进来。
  3. 真实的业务不是这样的。真实的业务是有10W个在线用户,ESB有100的并发,应用响应时间100ms,TPS就是(100并发/100ms)1000。即如果有100个线程阻塞了,其他用户会继续发送交易,ESB的实时并发数会涨起来,100 < 实时并发数 <= 200。

解决方案

  1. ESB的并发限制调大,如调成200(至少是实时并发数的2倍)
  2. 修改各个请求节点的connectTimeout时间,改成1S。
    注意不要修改成了readTimeout或是responseTimeout
  3. 修改测试方法1;并发数修改为1000,交易间隔1000ms,让应用TPS一样是1000,ESB线程数仍是100左右。压力机压一段时间后(让交易均匀分布到每秒钟),然后重启NODE。
  4. 修改测试方法2;我们要验证的是出现故障的情况,交易能持续进来,虽然有部分成功,但是不会造成阻塞;我们需要另外一台压力机,如并发数200,交易间隔100ms,Jmeter的responseTimeout为100ms(一般等于交易ART)。即Jmeter不等交易返回,不阻塞,持续发压力,验证系统能持续处理请求,并且预期TPS会提升。
  5. 修改测试方法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超时

参考

TCP超时时间20S问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值