天天看點

redis+crontab+php異步處理任務

2016年1月8日 16:08:43 星期五

情景: 使用者登入日志, 發郵件, 發短信等等實時性要求不怎麼高的業務通常會異步執行

之前接觸過幾種redis+crontab配套的實作方法,

比如: crontab定時執行curl腳本

  1. 用curl 通路URL執行PHP腳本去pop隊列

  2. PHP程式pop一次, 處理後傳回同樣的URL

  3. curl收到這個URL後就可以再次跟蹤通路并執行該PHP程式, 這樣就可以實作循環pop的效果

  4. 這樣需要給curl設定下最大跟蹤次數(--max-redirs), 就可以限定每次pop的最大值

  但總感覺那麼不順暢

  1. 不是實時的, 最高頻率是每隔一分鐘執行一次(當然也有其它方法使之能每秒都運作)

  2. 不同時間段打入隊列的資料是不确定的, 比如白天登入使用者會比晚上多, crontab執行頻率設定不合理的話, 比如,白天入隊列的資料可能大于出隊列的資料進而導緻延時加大

這兩天學到了一個新的方法, 可以解決實時性的問題:

PHP程式: 一個阻塞型的死循環去pop隊列

crontab:去監控這個PHP循環是不是在運作, 沒有則啟動

PHP程式:

注意:

1. while true, 看似是死循環, 但是裡邊的brpop是阻塞型的代碼, 隊列裡邊沒有資料的時候會讓出CPU直到資料的到來, 等待10秒鐘後還沒有資料就停掉, 進入下一次循環(下一個10s)

2. 因為是死循環, 要一直執行下去, 是以最好的方式是php_cli模式下執行, 這個模式下是不會有逾時限制的

3. "read error on connection" 報錯, 因為brpop阻塞10s, 是以PHP在連接配接redis時設定的timeout時間必須得大于這個時間, 或者幹脆就不設定逾時:

crontab怎麼配合: 定期檢查這個PHP腳本是否是在執行, 如果沒有就啟動它

start.sh:

這中實作方式可以達到實時的

但是沒資料的時候, 死循環會一直阻塞下去, 但貌似也不耗費什麼資源

上一篇: rsa加密解密
下一篇: 版本号對比