NAT网关连接数过高,问题排查记录

1. 问题的起因

运维同学反馈,集群的 NAT网关 的 tcp连接数过高,存在丢包风险

wecom-temp-9084baab90ffd71105ac0569ebe86b64

2. 问题排查过程

  • 先让中间件的同学在集群的NAT网关服务器上,进行netstat 统计,初步定位到是请求外部系统a的连接数过高导致的问题

  • 再在nat上进行抓包发现,是在请求外部系统的时候,外部系统主动关闭tcp请求导致的tcp连接没有复用 1

  • HTTP1.1 默认情况下,是通过开启keepalive header来保持长连接的 2
  • 我们代码采用的是okhttp,并且使用了连接池,为啥会是短连接?
  • 搜索可以得知,okhttp设置 Connection: close 可以禁用keepalive 3
  • 但是因为之前nat上的抓包不完整,看不到http的header,所以在业务容器中重新抓包
    • ping 外部系统域名,得到域名对应的IP是 x.x.x.x
    • 抓包,抓100个报文,关于 x.x.x.x 这个IP,存储到/tmp/target.cap 这个文件 4
    • tcpdump -s 0 -c 100 host x.x.x.x -w /tmp/target.cap
    • 下载到本地
  • 查看http请求的header,果然找到了 Connection: close

  • 再看代码,果然有隐藏的梗,找到原因了

  • 经过讨论,在公网环境下,http短连接的稳定性更好
    • 所以结论是保持短连接,增加nat的公网ip数量,提高连接数上限
  1. tcp关闭连接wireshark抓包

  2. http长连接

  3. okhttp禁用keepalive

  4. tcpdump使用

/** * RECOMMENDED CONFIGURATION VARIABLES: EDIT AND UNCOMMENT THE SECTION BELOW TO INSERT DYNAMIC VALUES FROM YOUR PLATFORM OR CMS. * LEARN WHY DEFINING THESE VARIABLES IS IMPORTANT: https://disqus.com/admin/universalcode/#configuration-variables*/ /* var disqus_config = function () { this.page.url = PAGE_URL; // Replace PAGE_URL with your page's canonical URL variable this.page.identifier = PAGE_IDENTIFIER; // Replace PAGE_IDENTIFIER with your page's unique identifier variable }; */ (function() { // DON'T EDIT BELOW THIS LINE var d = document, s = d.createElement('script'); s.src = 'https://chenzz.disqus.com/embed.js'; s.setAttribute('data-timestamp', +new Date()); (d.head || d.body).appendChild(s); })();