记录高并发下连接数过多引发的问题性能调优
最近在对推送服务吞吐量进行提升优化,保证上游业务请求tps4000提升到tps8000,主要是减少了接口响应时间,保证业务方在总推送量不变和本地服务机器不增加的前提下,每秒的吞吐量提升,提升后自然短时间内tcp连接也增加很多,1.推送服务调用个推和其他推送厂商有http请求,2.业务方调用推送服务有http请求。没想打的是恰好这个连接数达到了UCloud云服务访问固定IP+端口连接数(超过6万)过多引发了故障。
UCloud云计算团队故障调查:
从原因可以看出,短时时间内大量连接占用导致问题,一方面UCloud云团队会进行服务器内核更新提升,另一方面推送服务也要优化掉这么多长连接。
1.在高峰期,登录堡垒机查看与TCP协议相关的统计数据,确实连接数达到6万多,大部分是tcp的TIME_WAIT状态占用。
2.回忆下tcp四次挥手过程,当客户端发起close连接时,会有2ms的TIME-WAIT等待确认时间,那就是因为这个等待占用了大量的连接数。
3.查看推送服务连接time-wait监控确实得到验证,连接数值与请求量成正比
新的改变
推送服务通过SDK包调用外网个推时,作为客户端的推送服务建立了大量连接,使用完进行关闭造成大量TIME_WAIT,查看下个推SDK代码发现,确实每次http请求都是短连接,调用后进行了主动关闭造成事故。
那第一优化看来就是在这了,调整个推SDK包,让个推提供http请求可以复用的方式,最终个推提供底层netty长连接方式调用的SDK,推送服务对一台机器进行上线,让我们看看效果:
绿色这台机器确实降低些,说明调用服务端使用长连接起了作用,但是剩余的更多TIME_WAIT是哪里导致的呢。
接下来登录堡垒机抓包,查看TCP的TIME_WAIT是哪些ip导致的。
发现10.10.186.88,10.9.166.112都是外网ip,已经使用了长连接调用外网,还有这么多短连接TIME_WAIT不应该的,
再看下发起关闭的客户端是推送服务的8080端口,而8080是入口的端口,说明这个短连接不是出口调用外网个推的tcp,而是业务方调用推送服务的tcp,这个时候推送服务作为服务端,接收来自业务方客户端的大量http请求导致TIME_WAIT,而根据TCP四次挥手的规则,客户端发送close,客户端才有TIME_WAIT,不应该是推送服务出现大量TIME_WAIT呢。想不明白,问题很棘手!
二次改变
HTTP 协议老的标准是HTTP/1.0,为了提高系统的效率,HTTP 1.0规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求。查看nginx日志,发现业务方通过外网域名调用都是http1.0,这个都是不能复用连接的,请求一次关一个,并且主动由推送服务的服务器关闭,肯定会有大量那种timewait的连接。
抓包数据来证明下:
1.tcpdump在堡垒机上拉下数据:tcpdump -s 0 -i eth0 host 10.9.137.125 -w /var/tmp/tcpbags.cap
2.用wireshark分析:推送服务(10.9.137.125),上游业务方(10.10.186.88)
这个图是一次完整的关闭的四次挥手过程,关闭动作是由推送服务(10.9.137.125)发起,关闭与上游业务方(10.10.186.88)建立的连接。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声