前言
項目是基于swoole開發(fā),框架也是公司內(nèi)自己開發(fā)的框架,并沒有用外界熱門的swoole框架,swoole是4.0.0版本。項目需要執(zhí)行大量的自動任務,框架是通過swoole的sendMessage方法將需要執(zhí)行的任務給到worker執(zhí)行。然而最近卻發(fā)現(xiàn)一些自動任務會莫名丟失,并沒有執(zhí)行的情況。
排查歷程
在發(fā)現(xiàn)自動任務丟失的時候,我也是第一時間認為,可能需要執(zhí)行的任務代碼出現(xiàn)BUG,導致執(zhí)行失敗。但是經(jīng)過排查,任務代碼是沒毛病的,那究竟是哪里出現(xiàn)了問題,導致任務丟了呢?百思不得其解~
經(jīng)過不斷的溯源,終于查到了swoole的sendMessage方法處。先來看看swoole文檔的sendMessage介紹:
sendMessage方法是會返回一個布爾值,通過檢查發(fā)現(xiàn)丟失的任務,都是因為sendMessage失敗了,根本就沒有觸發(fā)對應worker的onPipeMessage事件。但是,知道的同時也開始納悶了,怎么就發(fā)送消息失敗了呢?返回值只有一個布爾值,去哪里獲取報錯信息?
swoole還提供了另外一個獲取報錯信息的方法,那就是getLastError。
getLastError能獲取最后一次操作的錯誤碼。但是經(jīng)過調(diào)試,發(fā)現(xiàn)一個很無奈的問題,getLastError獲取不到任何錯誤碼,也不清楚是什么問題導致獲取不到,這讓我甚是頭疼。
后來只能去查一下swoole的日志,看是否能看出點端倪,結(jié)果還真有所發(fā)現(xiàn)。
“output buffer overflow”,意思大概是輸出緩存區(qū)溢出。再對比getLastError有可能的報錯,有兩種可能:
然后查閱了一下文檔關(guān)于buffer_output_size:
意思是每次發(fā)送數(shù)據(jù)的上限值,出BUG有可能是因為這個問題,立馬去添加了項目的buffer_output_size配置,改為128M。但是任務仍舊會出現(xiàn)丟失的情況。
那么就可能是另外一個問題,那就是發(fā)送緩存區(qū)已滿。再次查閱swoole文檔,找到了一項配置socket_buffer_size:
就是說發(fā)送到worker時是先放入緩存區(qū),那么就有可能緩存區(qū)滿了,塞不進去的情況。死馬當活馬醫(yī),立馬修改配置!
經(jīng)過長時間的觀察,任務不再出現(xiàn)丟失的情況。終于解決了這個頭疼的問題,Nice??!






