redis crontab php非同步處理任務

2021-09-22 12:12:53 字數 2511 閱讀 3991

2023年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

)

注意:1. while true, 看似是死迴圈, 但是裡邊的brpop是阻塞型的**, 佇列裡邊沒有資料的時候會讓出cpu直到資料的到來, 等待10秒鐘後還沒有資料就停掉, 進入下一次迴圈(下乙個10s)

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

3. "read error on connection" 報錯, 因為brpop阻塞10s, 所以php在連線redis時設定的timeout時間必須得大於這個時間, 或者乾脆就不設定超時:

1

$this->connect('redis_host', 'redis_port', 'global_time_out');

2$this->auth('redis_auth');

crontab怎麼配合: 定期檢查這個php指令碼是否是在執行, 如果沒有就啟動它

* * * * * /bin/sh /path/to/watch/bash_script/start.sh online

start.sh:

1 #!/bin/bash

2# 使用了 redis 的 brpop 函式去實時監控, 傳送報警郵件和簡訊

3# 先檢查是否啟動了該程序, 沒有的話就啟動

4# 保證該檔案是可執行的

5 # crontab: /bin/sh /path/to/shell.sh

env #env: online/test/someone

67 count=`ps -ef | grep process_name | grep -v "

grep

" | wc -l`

8 start_time=`date +%y-%m-%d_%x`

9if [ $count -eq 0 ] && [ online = "$1"

] #生產環境

10then

11echo $"

start redislog

"12 #code here: cd /path/to/onlien/webroot && /path/to/php/bin/php /path/to/shell/file/cli.php args >> /path/to/error.log 2>&1

1314

elif [ $count -eq 0 ] && [ test = "$1"

] #公共測試環境

15then

16echo $"

start redislog

"17 #code here: cd /path/to/test/webroot && /path/to/php/bin/php /path/to/shell/file/cli.php args >> /path/to/error.log 2>&1

1819

elif [ $count -eq 0

] #個人測試環境

20then

21echo $"

start redislog

"22 #code here: cd /path/to/someone/webroot && /path/to/php/bin/php /path/to/shell/file/cli.php args >> /path/to/error.log 2>&1

2324

else

25echo $"

redislog already running "26

fi

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

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

summerphp

Silverlight實現呼叫多個非同步任務

public enum actionstatus 這個記錄了任務的結果 public class actionresult 任務名稱 public string taskname 狀態 public actionstatus status 訊息 public string message 任務結果 ...

AsyncTask 非同步處理

1,object,用於指定doinbackground的引數 2,integer,用於指定onprogressupdate的引數 3,uri,用於指定doinbackground的返回型別和onpostexecute的引數型別 public class updatetask extends asyn...

AsyncTask非同步處理

非同步處理的目的 完成任務的同時不阻塞主線程 ui執行緒 涉及handler looper message thread四個物件。實現非同步的流程 主線程啟動thread 子執行緒執行並生成message looper獲取message並傳遞給handler handler逐個獲取message並進...