前言
项目是基于swoole开发,框架也是公司内自己开发的框架,并没有用外界热门的swoole框架,swoole是4.0.0版本。项目需要执行大量的自动任务,框架是通过swoole的sendMessage方法将需要执行的任务给到worker执行。然而最近却发现一些自动任务会莫名丢失,并没有执行的情况。
排查历程
在发现自动任务丢失的时候,我也是第一时间认为,可能需要执行的任务代码出现BUG,导致执行失败。但是经过排查,任务代码是没毛病的,那究竟是哪里出现了问题,导致任务丢了呢?百思不得其解~
经过不断的溯源,终于查到了swoole的sendMessage方法处。先来看看swoole文档的sendMessage介绍:
sendMessage方法是会返回一个布尔值,通过检查发现丢失的任务,都是因为sendMessage失败了,根本就没有触发对应worker的onPipeMessage事件。但是,知道的同时也开始纳闷了,怎么就发送消息失败了呢?返回值只有一个布尔值,去哪里获取报错信息?
swoole还提供了另外一个获取报错信息的方法,那就是getLastError。
getLastError能获取最后一次操作的错误码。但是经过调试,发现一个很无奈的问题,getLastError获取不到任何错误码,也不清楚是什么问题导致获取不到,这让我甚是头疼。
后来只能去查一下swoole的日志,看是否能看出点端倪,结果还真有所发现。
“output buffer overflow”,意思大概是输出缓存区溢出。再对比getLastError有可能的报错,有两种可能:
然后查阅了一下文档关于buffer_output_size:
意思是每次发送数据的上限值,出BUG有可能是因为这个问题,立马去添加了项目的buffer_output_size配置,改为128M。但是任务仍旧会出现丢失的情况。
那么就可能是另外一个问题,那就是发送缓存区已满。再次查阅swoole文档,找到了一项配置socket_buffer_size:
就是说发送到worker时是先放入缓存区,那么就有可能缓存区满了,塞不进去的情况。死马当活马医,立马修改配置!
经过长时间的观察,任务不再出现丢失的情况。终于解决了这个头疼的问题,Nice!!