记录一次 CLOSE_WAIT 问题排查和梳理

简介: 本文记录了一次排查CLOSE_WAIT过多问题的经历和事后梳理学习的过程

环境描述

要说清楚事情,不介绍下背景和环境好像不行啊

背景

  • 公司内部有一套RPC服务框架,java开发的,rpc协议用的redis
  • 我所在的部门没java人手,但夸部门的数据交互又越来越多,一开始用http 接口性能不好,qps到2-3千的时候调用方经常发生各种curl 网络错误,导致拿不到数据,影响很不好
  • 所以后来自己拿 php+swoole 实现RPC服务,延用公司的框架,协议和服务注册啥的都保持一致,就是具体业务用php来实现

数据流转示意图

moa_

  • 绿色那块-中间椭圆的就是这次出问题的服务
  • 我们可能会被PHP-FPM和其他RPC服务请求,也可能请求其他RPC服务和DB, 这样说应该清楚了吧

发现和排查解决

  • 发现:收到zabbix发的报警 PROBLEM: system close_wait [9522>5300], 首次报警
  • 脑子想了下,通常如果出问题都是调用方反馈,这次调用方没反馈应该没影响到具体业务,也没啥其它好确认的,直接上服务器看吧
  • ss -ant | grep CLOSE-WAIT 确认下果然是这样
  • close-wait 具体含义简单说下,看图
  • tcp_close
  • 这是tcp的挥手图,当主动关闭的一方发出FIN包,被动方回复ACK后自己就进入CLOSE_WAIT状态,正常情况下,被动方稍后就应该发出FIN包,并确认收到ACK回复,然后连接就可以正常关闭了
  • 很显然由于某些原因,我们的swoole程序(被动方)没能发出FIN包,这个为什么回头再分析,先把报警解决了
  • close_wait 是不会自动消失的,根据上面ss -ant 结果配合 lsof -i :{$port} 查到具体的服务,隔离-重启-恢复这个服务, 当然了ss -ant 的结果要保存下来,等下要分析具体谁跟我断了。。。

原因分析和调整

分析

  • ss -ant 的结果看了下,close_wait 的 Foreign Address 基本都是RPC(java), 很多都是常用服务,整个公司都在用,基本排除是对方的原因
  • 这次有2台机器都出现了问题,但2台机器上引起close_wait的service进程是不一样的,但有个特征就是请求量很少

所以大胆推测对方主动断开的原因是这样的

  • 因为 swoole 不忙,导致建立的socket连接超过了闲置时间,然后对方就觉得timeout了,然后主动断开了
  • 还注意到close_wait 对方很多是按理不应该用到的rpc服务,我猜这个应该是php代码没写好有关系。 看开头的背景也知道,用swoole搭服务时间还是很紧张的,业务逻辑基本都是直接用的http api那套代码,而swoole是常驻内存的,本来某些变量/连接在api那套里面随着请求结束就回收了,但是在swoole里不会

接着在分析下swoole为什么在被动关闭时为什么没发FIN

  • 看了下官方的onClose说明,有说到onClose回调函数如果发生了致命错误,会导致连接泄漏。通过netstat命令会看到大量CLOSE_WAIT状态的TCP连接
  • 我觉得基本就是onClose这里出了问题;我看了下php的error log, 没发现fatal error;
  • 我们4台机器,其中2台发生问题,而且是不同的服务。加上用关键字swoole close wait google 没有发现案例。基本排除是swoole的问题,还是我使用的姿势不对然后有几率导致发生这个问题
  • 然后就没有然后了,这4个机器的服务也跑了一年多了,第一次发生这个情况,我又不懂系统原理和c,加上案发现场现在也关闭了

调整

  • 这2个不活跃的服务配置的worker num 都是96个, 其中一个是同事开发的,使用的默认配置(默认配置是有个配置文件,我弄的,我好像没讲过要调低),另一个一开始请求量多,后来业务下了,也忘了调低
  • 整理了下,请求量低的服务 worker number 都调低

经验总结

  • 系统原理网络c语言 要尽量多学习, 不然承担这种基础架构服务,万一出了底层问题,你就不太能搞的定了,都是只能治标,不能治本
相关文章
|
缓存
SpringCloud Gateway 网关的请求体body的读取和修改
SpringCloud Gateway 框架中,为了处理请求体body,实现多次读取与修改,创建了一个名为`RequestParamGlobalFilter`的全局过滤器。这个过滤器使用`@Component`和`@Slf4j`注解,实现了`GlobalFilter`和`Ordered`接口,设置最高优先级以首先读取body。它通过缓存请求体并创建装饰过的`ServerHttpRequest`来实现body的动态获取。
1530 4
|
应用服务中间件 Linux
Tomcat不定期close_wait过多
Tomcat不定期close_wait过多
528 0
|
运维 Linux Windows
【计算巢】幻兽帕鲁服务器如何设置定时备份存档
计算巢针对幻兽帕鲁服务器,提供给了定时备份存档的功能,会在设定的频率下,定时将存档文件备份到目标文件夹下,有助于解决存档丢失和坏档的问题。
|
存储 缓存 监控
美团面试:说说OOM三大场景和解决方案? (绝对史上最全)
小伙伴们,有没有遇到过程序突然崩溃,然后抛出一个OutOfMemoryError的异常?这就是我们俗称的OOM,也就是内存溢出 本文来带大家学习Java OOM的三大经典场景以及解决方案,保证让你有所收获!
4444 0
美团面试:说说OOM三大场景和解决方案? (绝对史上最全)
|
Java 应用服务中间件 Spring
记录SpringCloudGateway的一个隐藏问题
线上生产环境中,一个SCG接口偶发性出现“Connection reset by peer”错误。排查发现问题是由于Netty的HTTP客户端连接池保持了已由服务端关闭的连接。解决方案是配置连接池以在超时后回收连接(超时时间应小于Tomcat的连接超时时间),并考虑将连接池获取策略从FIFO改为LIFO,以减少使用无效连接的可能性。通过修改Spring Cloud Gateway的HTTP客户端连接池配置和添加JVM启动参数可以实现这一修复。
2639 1
|
canal 关系型数据库 MySQL
四种常用的 MySQL 数据同步 ES 的方法
【2月更文挑战第16天】
4226 2
四种常用的 MySQL 数据同步 ES 的方法
|
XML Java 程序员
保姆级教程,手把手教你实现SpringBoot自定义starter
保姆级教程,手把手教你实现SpringBoot自定义starter
12004 2
保姆级教程,手把手教你实现SpringBoot自定义starter
|
网络协议 应用服务中间件
服务器CLOSE_WAIT请求太多的问题
服务器CLOSE_WAIT请求太多的问题
724 0
|
Prometheus Kubernetes Cloud Native
Flagger(应用自动发布)介绍和原理剖析
## 简介 [Flagger](https://github.com/weaveworks/flagger)是一个能使运行在k8s体系上的应用发布流程全自动(无人参与)的工具, 它能减少发布的人为关注时间, 并且在发布过程中能自动识别一些风险(例如:RT,成功率,自定义metrics)并回滚. ## 主要特性 ![features](https://intranetproxy.ali
4747 0
|
存储 Python Windows
windows创建python虚拟环境
本文有2种创建python虚拟环境的方式, 如果第二种方式有问题, 建议使用第一种方式!
windows创建python虚拟环境