1、進程之間不共享任何狀態
2、進程的調度由操作系統完成
3、每個進程都有自己獨立的內存空間
4、進程間通訊主要是通過信號傳遞的方式來實現的,實現方式有多種,信號量、管道、事件等,任何一種方式的通訊效率都需要過內核,導致通訊效率比較低
5、由于是獨立的內存空間,上下文切換的時候需要保存先調用棧的信息、cpu各寄存器的信息、虛擬內存、以及打開的相關句柄等信息,所以導致上下文進程間切換開銷很大,通訊麻煩。
1、線程之間共享變量,解決了通訊麻煩的問題對于變量的訪問需要鎖
2、一個進程可以擁有多個線程,但是其中每個線程會共享父進程像操作系統申請資源,這個包括虛擬內存、文件等,由于是共享資源,所以創建線程所需要的系統資源占用比進程小很多,相應的可創建的線程數量也變得相對多很多。
3、另外在調度方面也是由于內存是共享的,所以上下文切換的時候需要保存的東西就像對少一些,這樣一來上下文的切換也變得高效。
1、Master進程:主進程
2、Manger進程:管理進程
3、Worker進程:工作進程
4、Task進程:異步任務工作進程
第一層,Master進程,這個是swoole的主進程,這個進程是用于處理swoole的核心事件驅動的,那么在這個進程當中可以看到它擁有一個MainReactor[線程]以及若干個Reactor[線程],swoole所有對于事件的監聽都會在這些線程中實現,比如來自客戶端的連接,信號處理等。
1.1、MainReactor(主線程)
主線程會負責監聽server socket,如果有新的連接accept,主線程會評估每個Reactor線程的連接數量。將此連接分配給連接數最少的reactor線程,做一個負載均衡。
1.2 、Reactor線程組
Reactor線程負責維護客戶端機器的TCP連接、處理網絡IO、收發數據完全是異步非阻塞的模式。
swoole的主線程在Accept新的連接后,會將這個連接分配給一個固定的Reactor線程,在socket可讀時讀取數據,并進行協議解析,將請求投遞到Worker進程。在socket可寫時將數據發送給TCP客戶端。
1.3、心跳包檢測線程(HeartbeatCheck)
Swoole配置了心跳檢測之后,心跳包線程會在固定時間內對所有之前在線的連接
發送檢測數據包
1.4、UDP收包線程(UdpRecv)
接收并且處理客戶端udp數據包
swoole想要實現最好的性能必須創建出多個工作進程幫助處理任務,但Worker進程就必須fork操作,但是fork操作是不安全的,如果沒有管理會出現很多的僵尸進程,進而影響服務器性能,同時worker進程被誤殺或者由于程序的原因會異常退出,為了保證服務的穩定性,需要重新創建worker進程。
Swoole在運行中會創建一個單獨的管理進程,所有的worker進程和task進程都是從管理進程Fork出來的。管理進程會監視所有子進程的退出事件,當worker進程發生致命錯誤或者運行生命周期結束時,管理進程會回收此進程,并創建新的進程。換句話也就是說,對于worker、task進程的創建、回收等操作全權有“保姆”Manager進程進行管理
worker 進程屬于swoole的主邏輯進程,用戶處理客戶端的一系列請求,接受由Reactor線程投遞的請求數據包,并執行PHP回調函數處理數據生成響應數據并發給Reactor線程,由Reactor線程發送給TCP客戶端可以是異步非阻塞模式,也可以是同步阻塞模式
taskWorker進程這一進城是swoole提供的異步工作進程,這些進程主要用于處理一些耗時較長的同步任務,在worker進程當中投遞過來。
1、client請求到達 Main Reactor,Client實際上是與Master進程中的某個Reactor線程發生了連接。
2、Main Reactor根據Reactor的情況,將請求注冊給對應的Reactor (每個Reactor都有epoll。用來監聽客戶端的變化)
3、客戶端有變化時Reactor將數據交給worker來處理
4、worker處理完畢,通過進程間通信(比如管道、共享內存、消息隊列)發給對應的reactor。
5、reactor將響應結果發給相應的連接請求處理完成
<?php//tcp協議$server=new Swoole\Server("0.0.0.0",9800); //創建server對象$server->set([ 'worker_num'=>3, //設置進程 //'heartbeat_idle_time'=>10,//連接最大的空閑時間 //'heartbeat_check_interval'=>3 //服務器定時檢查 'open_length_check'=>1, 'package_length_type'=>'N',//設置包頭的長度 'package_length_offset'=>0, //包長度從哪里開始計算 'package_body_offset'=>4, //包體從第幾個字節開始計算 'package_max_length'=>1024 * 1024 * 2,]);$server->on("Start",function (){ var_dump(1); //設置主進程的名稱 swoole_set_process_name("server-process:master");});//服務關閉時候觸發(信號)$server->on("shutdown",function (){});//當管理進程啟動時調用它$server->on('ManagerStart',function (){ var_dump(2); //swoole_set_process_name("server-process:manger");});$server->on('WorkerStart',function ($server,$workerId){ // swoole_set_process_name("server-process:worker"); var_dump(3);});//監聽事件,連接事件(woker進程當中)$server->on('connect',function ($server,$fd){ echo "新的連接進入:{$fd}".PHP_EOL;});//消息發送過來(woker進程當中)$server->on('receive',function (swoole_server $server, int $fd, int $reactor_id, string $data){ //var_dump("消息發送過來:".$data); //服務端});//消息關閉$server->on('close',function (){ echo "消息關閉".PHP_EOL;});//服務器開啟$server->start();echo '123456';
1、進程之間不共享任何狀態
2、進程的調度由操作系統完成
3、每個進程都有自己獨立的內存空間
4、進程間通訊主要是通過信號傳遞的方式來實現的,實現方式有多種,信號量、管道、事件等,任何一種方式的通訊效率都需要過內核,導致通訊效率比較低
5、由于是獨立的內存空間,上下文切換的時候需要保存先調用棧的信息、cpu各寄存器的信息、虛擬內存、以及打開的相關句柄等信息,所以導致上下文進程間切換開銷很大,通訊麻煩。
1、線程之間共享變量,解決了通訊麻煩的問題對于變量的訪問需要鎖
2、一個進程可以擁有多個線程,但是其中每個線程會共享父進程像操作系統申請資源,這個包括虛擬內存、文件等,由于是共享資源,所以創建線程所需要的系統資源占用比進程小很多,相應的可創建的線程數量也變得相對多很多。
3、另外在調度方面也是由于內存是共享的,所以上下文切換的時候需要保存的東西就像對少一些,這樣一來上下文的切換也變得高效。
1、Master進程:主進程
2、Manger進程:管理進程
3、Worker進程:工作進程
4、Task進程:異步任務工作進程
第一層,Master進程,這個是swoole的主進程,這個進程是用于處理swoole的核心事件驅動的,那么在這個進程當中可以看到它擁有一個MainReactor[線程]以及若干個Reactor[線程],swoole所有對于事件的監聽都會在這些線程中實現,比如來自客戶端的連接,信號處理等。
1.1、MainReactor(主線程)
主線程會負責監聽server socket,如果有新的連接accept,主線程會評估每個Reactor線程的連接數量。將此連接分配給連接數最少的reactor線程,做一個負載均衡。
1.2 、Reactor線程組
Reactor線程負責維護客戶端機器的TCP連接、處理網絡IO、收發數據完全是異步非阻塞的模式。
swoole的主線程在Accept新的連接后,會將這個連接分配給一個固定的Reactor線程,在socket可讀時讀取數據,并進行協議解析,將請求投遞到Worker進程。在socket可寫時將數據發送給TCP客戶端。
1.3、心跳包檢測線程(HeartbeatCheck)
Swoole配置了心跳檢測之后,心跳包線程會在固定時間內對所有之前在線的連接
發送檢測數據包
1.4、UDP收包線程(UdpRecv)
接收并且處理客戶端udp數據包
swoole想要實現最好的性能必須創建出多個工作進程幫助處理任務,但Worker進程就必須fork操作,但是fork操作是不安全的,如果沒有管理會出現很多的僵尸進程,進而影響服務器性能,同時worker進程被誤殺或者由于程序的原因會異常退出,為了保證服務的穩定性,需要重新創建worker進程。
Swoole在運行中會創建一個單獨的管理進程,所有的worker進程和task進程都是從管理進程Fork出來的。管理進程會監視所有子進程的退出事件,當worker進程發生致命錯誤或者運行生命周期結束時,管理進程會回收此進程,并創建新的進程。換句話也就是說,對于worker、task進程的創建、回收等操作全權有“保姆”Manager進程進行管理
worker 進程屬于swoole的主邏輯進程,用戶處理客戶端的一系列請求,接受由Reactor線程投遞的請求數據包,并執行PHP回調函數處理數據生成響應數據并發給Reactor線程,由Reactor線程發送給TCP客戶端可以是異步非阻塞模式,也可以是同步阻塞模式
taskWorker進程這一進城是swoole提供的異步工作進程,這些進程主要用于處理一些耗時較長的同步任務,在worker進程當中投遞過來。
1、client請求到達 Main Reactor,Client實際上是與Master進程中的某個Reactor線程發生了連接。
2、Main Reactor根據Reactor的情況,將請求注冊給對應的Reactor (每個Reactor都有epoll。用來監聽客戶端的變化)
3、客戶端有變化時Reactor將數據交給worker來處理
4、worker處理完畢,通過進程間通信(比如管道、共享內存、消息隊列)發給對應的reactor。
5、reactor將響應結果發給相應的連接請求處理完成
<?php//tcp協議$server=new Swoole\Server("0.0.0.0",9800); //創建server對象$server->set([ 'worker_num'=>3, //設置進程 //'heartbeat_idle_time'=>10,//連接最大的空閑時間 //'heartbeat_check_interval'=>3 //服務器定時檢查 'open_length_check'=>1, 'package_length_type'=>'N',//設置包頭的長度 'package_length_offset'=>0, //包長度從哪里開始計算 'package_body_offset'=>4, //包體從第幾個字節開始計算 'package_max_length'=>1024 * 1024 * 2,]);$server->on("Start",function (){ var_dump(1); //設置主進程的名稱 swoole_set_process_name("server-process:master");});//服務關閉時候觸發(信號)$server->on("shutdown",function (){});//當管理進程啟動時調用它$server->on('ManagerStart',function (){ var_dump(2); //swoole_set_process_name("server-process:manger");});$server->on('WorkerStart',function ($server,$workerId){ // swoole_set_process_name("server-process:worker"); var_dump(3);});//監聽事件,連接事件(woker進程當中)$server->on('connect',function ($server,$fd){ echo "新的連接進入:{$fd}".PHP_EOL;});//消息發送過來(woker進程當中)$server->on('receive',function (swoole_server $server, int $fd, int $reactor_id, string $data){ //var_dump("消息發送過來:".$data); //服務端});//消息關閉$server->on('close',function (){ echo "消息關閉".PHP_EOL;});//服務器開啟$server->start();echo '123456';
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com