過去半年使用PHP和Java兩種技術堆疊完成了一個遊戲伺服器專案。由於專案中有高頻的網路請求,所以PHP技術堆疊嘗試使用Swoole引擎(基於事件的高效能非同步並行網路通訊引擎)來完成部分遊戲業務。
推薦(免費):swoole
#Swoole的安裝
安裝swoole很簡單,由於是國人做的項目,許多issue可以在官網文件找到答案。安裝分兩種:
具體操作百度一下即可,網路上相關內容很多。
Swoole引擎的優點
Swoole引擎的流程解析
Swoole執行的流程圖如下:
# #Swoole中的執行緒或行程
結構圖如下:#Swoole引擎分為兩種模式:單一執行緒模式和進程模式。本文只討論進程模式。具體兩者區別官方文件中有說明。Master程序用於處理swoole核心事件,例如來自客戶端的連接,本地通訊的管道。 master行程裡有多個線程,每個線程都運行了一個epol函數的實例。 (由於Worker進程不是由Master進程fork出來的,所以可能會出現強行kill Master進程後,Worker進程依舊存在)Reactor線程Swoole的主進程是一個多線程的程序。其中有一組很重要的線程,稱為Reactor線程。它就是真正處理TCP連接,收發資料的線程。
Swoole的主線程在Accept新的連接後,會將這個連接分配給一個固定的Reactor線程,並由這個線程負責監聽此socket。在socket可讀時讀取數據,並進行協定解析,將請求投遞到Worker進程。在socket可寫時將資料傳送給TCP客戶端
子程序結束執行時,manager程序負責回收此子程序,避免成為殭屍程序。並建立新的子程序
伺服器關閉時,manager程序將發送訊號給所有子程序,通知子程序關閉服務
伺服器reload時,manager程序會逐一關閉/重新啟動子程序
各行程的回呼函數
Master內的回呼函數:Manager程序內的回呼函數
Reactor、Worker、TaskWorker的關係
#可以理解為Reactor就是nginx,Worker就是php-fpm。 Reactor執行緒非同步並行地處理網路請求,然後再轉送給Worker進程中去處理。 Reactor和Worker間透過UnixSocket進行通訊。
在php-fpm的應用中,常常會將一個任務非同步投遞到Redis等佇列中,並在背景啟動一些php進程非同步地處理這些任務。 Swoole提供的TaskWorker是一套更完整的方案,將任務的投遞、佇列、php任務處理程序管理合為一體。透過底層提供的API可以非常簡單地實現非同步任務的處理。另外TaskWorker還可以在任務執行完成後,再回傳一個結果回傳到Worker。
Swoole的Reactor、Worker、TaskWorker之間可以緊密的結合起來,提供更進階的使用方式。一個更通俗的比喻:假設Swoole應用伺服器是一個工廠,那麼Reactor就是銷售,接受客戶訂單。而Worker就是工人,當銷售接到訂單後,Worker去工作生產客戶要的東西。而TaskWorker可以理解為行政人員,可以幫助Worker做些雜事,讓Worker專心工作。
底層會為Worker進程、TaskWorker進程分配一個唯一的ID。不同的Worker和TaskWorker進程之間可以透過sendMessage介面進行通訊。
實際專案中的各行程執行緒的分工:
Swoole版本相容性
該專案開發階段使用的swoole引擎版本1.9.6,後來由於測試環境安裝成了4.3.2版本,所以嘗試業務程式碼作調整。不過swoole的向下相容很值得佩服的是,這過程中竟然只發現了一處代碼不相容的問題:是有關swoole_server的一項配置參數,在原來版本採用了魔鬼數字進行配置的,但是到新版本,這個數字沒有被巨集定義,後來透過查看swoole源碼找到了巨集定義組,然後修改了這處組態。 (不過版本升級順利也是基於swoole的業務代碼比較少,所以僅供參考
更多相關學習推薦:swoole教程
以上是分享Swoole引擎原理的快速入門乾貨的詳細內容。更多資訊請關注PHP中文網其他相關文章!