我現(xiàn)在采用的做法是在workerman中啟動一個Timer來檢測queue進程數(shù),如果進程不足則重啟。但是這種輪詢很不優(yōu)雅。畢竟要等一輪interval才能進行檢測。尤其是當queue設置了--stop-when-empty選項時,每次執(zhí)行完隊列會自動退出進程,那么下次有任務推入隊列時,要保證隊列實時性就比較困難(假設interval設置得較大)。
我有個方案,workerman監(jiān)聽一個端口,并設置onClose回調。
laravel queue 進程啟動后發(fā)起一個連接連workerman這個端口。
如果laravel queue 進程掛掉,那么連接也會close,workerman的onClose就會觸發(fā)。
onClose觸發(fā)時去檢查laravel queue 是否掛掉。這樣監(jiān)控是最實時的,但是挺麻煩的。
我現(xiàn)在還采用了另一個方案,啟動queue進程是永不退出的,workerman的工作進程作為守護進程來檢測queue進程數(shù)量,這樣有queue進程異常退出導致進程數(shù)不足時,workerman的工作進程可以補足數(shù)量。這樣做可以把timer間隔設得比較大,事件推入隊列也是實時的,因為隨時有隊列進程在等著接收事件。唯一的缺陷是,我在worker stop --d的時候,如果想同步停止隊列,需要在onWorkerStop去調用一個shell腳本來kill隊列進程,laravel queue本身也并沒有提供一個優(yōu)雅的stop方法,導致這個kill腳本很可能會執(zhí)行失敗,這個情況下,workerman會出現(xiàn)一個死循環(huán)的exit with status 9異常,不停寫日志,我前面好像發(fā)過issue。或者說kill時隊列里還有未完成的任務,會積累到下次重啟隊列才能糾錯。無論哪一種,都談不上優(yōu)雅。
是否可以在onWorkerStop 里面像隊列進程發(fā)送一個停止的信號,甚至可以是一個停止的隊列任務(這個隊列任務優(yōu)先級最高),從而讓隊列自己退出自己
用laravel Horizon 不是更好么,動態(tài)進程數(shù),而且進程數(shù)我覺得開你能接受的最大就行,反正沒任務的時候進程在阻塞掛起,幾乎不耗CPU