一次生产问题,gateway-worker导致php进程飙升

ixlara

问题描述

项目是用gateway-worker写的,共有2000个连接左右。正常情况下设备连接好后进行正常通信,维护业务逻辑即可。
上周生产环境突然cpu飙升,导致所有业务异常,排查发现注册指令被频繁访问,
设备商反馈设备需要三秒内回复,回复不及时会再次注册。

想问问什么情况下会导致回复不及时,消息处理不完导致阻塞?如何解决?

程序代码

截图

操作系统及workerman/webman等框架组件具体版本

"workerman/mqtt":1.7
"workerman/workerman": 4.1.17
"workerman/gateway-worker":3.1.18
"workerman/gatewayclient": 3.0.17

474 10 5
10个回答

tanhongbin

这种回复不及时 是调用第三方接口 相应慢嘛?

  • ixlara 15天前

    按道理不应该,就是数据库交互。看了那天事故期间数据库日志也没啥问题

walkor 打赏

php start.php status
贴下

ixlara

截图

  • walkor 15天前

    执行
    cat /proc/28658/limits

  • ixlara 15天前

    cat /proc/28658/limits 贴在下楼了

ixlara

截图

  • 暂无评论
walkor 打赏

设备要求3秒内回复注册消息,如果没回复则再次注册。
2000台设备,如果gateway-worker重启,会导致2000设备同时发送注册请求,如果服务端无法及时在3秒内回复,则设备会继续发起注册请求,如此循环。
所以这里有个风险,当服务端处理不过来这些注册消息时,2000设备会不断发送请求,那么就会发生你说的情况。

解决方案:
多开一些businessWorker进程来增加处理速度,例如开到cpu的4-8倍或者更高。
优化业务,减少数据库等调用,减少不必要的gateway::xxx()接口调用,加快业务处理速度。
减少gateway进程可以降低内部接口调用的负载,少于1万设备gateway进程数可以设置为1-2。
尽量不要重启gateway进程。

如果再次发生了因为不断发送注册请求导致cpu高的问题,可以每隔3秒执行 php start.php reload,这样可以清理请求队列里过期的注册请求,快速恢复服务。

最后
如果问题还未解决,请保留现场 php start.php statustop 命令的结果。
从top命令中能看出哪个进程占用cpu高,假设是pid为28658的进程
执行 strace -ttp 28658 查看进程的系统调用,能大概定位出进程为什么cpu高。
请把上面结果截图发到这里来

  • ixlara 15天前

    好的 大佬 ,先按你的方案改进试下
    还有个疑问,
    我们最近重启过多次gateway。我理解其实每次都是模拟的一次设备重连的过程,一直也没事。就上周在没重启状态下设备批量重连。
    如果每次BusinessWorker内代码有变更,可以直接杀掉businessWorker进程,达到代码热加载,并且不重启gateway么?

  • walkor 15天前

    执行reload 会自动热加载businessWorker进程业务,不重启gateway。

  • walkor 15天前

    没重启大量设备重连可能是因为服务器网络问题导致全部设备掉线。
    也可能是业务代码因为调用什么操作导致阻塞长时间超时,大量设备因为超时重新不断发起请求,大量请求积压。
    也可能是其他没有想到的原因

  • ixlara 15天前

    好的 谢谢 我去试试

JonWong

蹲个后续,怎么解决的来

  • 暂无评论
ab0029

思路清晰

  • 暂无评论
andyzu

蹲个后续,怎么解决的来

  • 暂无评论
码上有闲

留个位置

  • 暂无评论
ixlara

短解方案:
1、workerman加日志
2、压测
3、根据压测数据增加businessWorker数量

其实我觉得发生这次事故的根本原因还是没找到的,所以这次只是一个短解方案。
加上了日志,看会不会复现。等复现保留好现场数据再分析

  • 暂无评论
×
🔝