1.swoole 的進程模型
swoole是一個多進程模型的框架,當啓動一個進程swoole應用時,一共會創建2+n+m個進程,n爲worker進程數,m爲TaskWorker進程數,1個master進程和一個manager進程,關係如下圖所示
Master進程爲主進程,該進程會創建Manager進程、Reactor線程等工作進/線程
其中三種進程之間的關係是:
Reactor線程:
- 負責維護客戶端
TCP
連接、處理網絡IO
、處理協議、收發數據 - 完全是異步非阻塞的模式
- 全部爲
C
代碼,除Start
/Shudown
事件回調外,不執行任何PHP代碼 - 將
TCP
客戶端發來的數據緩衝、拼接、拆分成完整的一個請求數據包 Reactor
以多線程的方式運行
Worker進程
- 接受由
Reactor
線程投遞的請求數據包,並執行PHP
回調函數處理數據 - 生成響應數據併發給
Reactor
線程,由Reactor
線程發送給TCP
客戶端 - 可以是異步非阻塞模式,也可以是同步阻塞模式
Worker
以多進程的方式運行
TaskWorker進程
- 接受由
Worker
進程通過swoole_server->task/taskwait
方法投遞的任務 - 處理任務,並將結果數據返回(使用
swoole_server->finish
)給Worker
進程 - 完全是同步阻塞模式
TaskWorker
以多進程的方式運行
2.swoole代碼
開啓taskworker需要配置task_worker_num的數量
$this->serv->set(['worker_num'=>4,'task_worker_num'=>4,'daemonize'=>false]);
還需要實現回調方法,onTask,onFinish
$this->serv->on('Task',[$this,'onTask']);
$this->serv->on('Finish',[$this,'onFinish']);
Task 簡介
task進程是swoole當中獨立於worker進程的工作進程。用於處理一些耗時較長的邏輯,這些邏輯如果在工作當中處理時並不會影響worker進程處理來自於客戶端的請求。由此大大提高了swoole擴展的併發能力。
在worker進程當中,通過調用 task() 方法,發送數據通知到task進程,task進程會在 onTask() 回調當中接收到這些數據並進行處理,處理完成之後調用 finish() 函數或者直接return返回消息給 worker進程,worker進程的 onFinish() 函數收到這些數據並進行處理。
注意:
Task進程和worker進程間通過 Unix Sock 管道通信(也可配置通過消息隊列通信)
Task 常見問題
Task傳遞數據大小(Task傳遞數據本身是沒有限制的)
數據小於8k:直接通過管道傳遞;
數據大於8k:寫入臨時文件傳遞。
Task 傳遞對象(Task參數傳遞對象的問題)
可以通過序列化傳遞一個對象的拷貝(也就是說,並不是傳遞了一個引用,因爲在Task當中,它和worker進程是兩個完全不同的進程,他們的內存空間是不一樣的,因此變量存儲的地方也不一樣,所以,Task對於一個對象的改變並不會反映到woker進程中);
數據庫連接,網絡連接對象不可這樣傳遞,會引起 PHP 程序報錯。
Task 的 onFinish 回調
Task 的 onFinish 回調會發回調用task方法的worker進程(回調給調用它方法的worker進程,並不會回調給其他worker進程)