今天生产突然遇到一个问题. 一个内部的http 接口服务.

master 进程内存溢出, 快速增长内存 问题.

想了很多 也看了很多日志. 发现服务器 php_error.log 在提示内存溢出写入日志内存失败.

[05-Apr-2024 20:56:09 Asia/Shanghai] PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 20382400 bytes) in FileLog.php on line 217

通过调试发现和 大佬们说的一样:

2024-04-05T13:05:10.png

主进程内存占用过高一般是有大量数据未发送保存在内存缓存区中,请开启心跳检测功能,剔除坏连接。

诶 我们这个问题还是 日志写的太大了. 导致 worker进程直接 Fatal 死掉了. Master 不主动释放, 日积月累服务器内存写满.

今天查看 /var/log/php_error.log 抛错如下:

[23-Feb-2024 13:17:34 Asia/Shanghai] PHP Warning:  Swoole\Http\Response::header(): http response is unavailable (maybe it has been ended or detached) in ../Listen/Http.php on line 216
[23-Feb-2024 13:17:34 Asia/Shanghai] PHP Warning:  Swoole\Http\Response::end(): http response is unavailable (maybe it has been ended or detached) in ../Listen/Http.php on line 218

问题很明显

http response is unavailable (maybe it has been ended or detached
译 : http响应不可用(可能已结束或分离)

http 协议请求回包前 连接找不到 提前在其他位置回包了 或者说 客户端主动断开了.

今天一台测试服务器 /tmp 下产生大量 swoole.task 临时文件 大概几十万个 将磁盘打满了 大概时间也就7天以内 , 这些文件什么鬼 ?? 是worker to task 的队列长度堵塞 生成的文件吗?

在测试服务器上, 有很多 swoole 服务程序, swoole.task 临时文件仍在增长, 所以我就依次 kill 服务. 终于找到问题服务在哪里了
这个服务的 task进程 子进程 manager进程 都已经死掉了.

====================== 活着的进程 ================================
root      4651 11357  0 17:31 pts/0    00:00:00 Knock-swoole-main-master     
root      4741     1  0 17:31 pts/0    00:00:07 Knock-swoole-worker-0    

====================== 死掉的进程 ================================
root      4652  4651  0 17:31 pts/0    00:00:00 Knock-swoole-main-manager     
root      4694     1  0 17:31 pts/0    00:00:00 Knock-sws-swoole-fork-process 
root      4740     1  4 17:31 pts/0    00:01:50 Knock-swoole-task-0               

总结了下原因如下 :

swoole 起得多进程脚本 worker 投递任务给 task 进程
但 不知什么原因 manager 进程 死掉了 task 进程过期后没有重新拉起
worker 投递的数据超过8180字节 产生了临时文件 (文档)
而且因为投递的任务未执行导致 worker 仍会重复投递 直至磁盘打满

当我想复现下问题, 但因为投递数据不超过 8180字节 所以在kill掉 上述进程后并没有临时文件产生.

近期遇到三个swoole 的抛错日志, 很头疼 有的有解释 有的并没有, 但总体也算是解决了问题.

[2023-11-21 19:44:02<.978122> #9118.2]  WARNING del (ERRNO 800): failed to delete events[430], it has already been removed

[2023-11-21 22:17:28<.225417> *19693.61] WARNING Worker_discard_data (ERRNO 1007): [2] ignore data[1272 bytes] received from session#15689

[2023-11-18 09:15:07 *22844.90] WARNING send_blocking(:206): send 40 bytes failed, Error: Resource temporarily unavailable[11]

继续阅读

根据提供的错误消息,这是一个关于Swoole服务的错误。错误消息中的WARNING timer_callback (ERRNO 9007): No idle worker is available表示没有空闲的工作进程可用。

这种情况通常发生在Swoole服务的工作进程池已满,无法处理更多的请求或任务。当所有工作进程都在忙于处理请求时,新的请求将无法得到处理,从而导致该警告出现。

解决该问题的方法可以考虑以下几点:

  1. 增加工作进程数:可以通过增加Swoole服务的工作进程数来扩展处理能力。可以在Swoole的配置文件或代码中找到关于工作进程数的设置项,并适当增加工作进程的数量。
  2. 优化代码逻辑:检查Swoole服务中的代码逻辑,确保没有长时间阻塞的操作或耗时过长的任务。如果存在耗时操作,可以考虑使用异步或并发处理方式,以充分利用工作进程资源。
  3. 调整资源限制:检查服务器的资源限制,例如文件句柄数、内存限制等。确保这些限制不会导致工作进程无法创建或执行。
  4. 监控和调优:使用合适的监控工具来监视Swoole服务的性能指标,例如请求处理速度、工作进程状态等。根据监控结果进行调优,找出性能瓶颈并进行相应的优化。

以上是一些常见的解决方法,但具体的解决方案可能需要根据你的具体应用和环境来确定。建议查看Swoole文档和相关技术资源,以获取更详细的指导和建议。

karp

创建我自己的巨人