前言
項目是基于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!!