首頁  >  文章  >  php框架  >  分享Swoole引擎原理的快速入門乾貨

分享Swoole引擎原理的快速入門乾貨

coldplay.xixi
coldplay.xixi轉載
2021-03-12 11:01:181985瀏覽

分享Swoole引擎原理的快速入門乾貨

過去半年使用PHP和Java兩種技術堆疊完成了一個遊戲伺服器專案。由於專案中有高頻的網路請求,所以PHP技術堆疊嘗試使用Swoole引擎(基於事件的高效能非同步並行網路通訊引擎)來完成部分遊戲業務。

推薦(免費):swoole

#Swoole的安裝

安裝swoole很簡單,由於是國人做的項目,許多issue可以在官網文件找到答案。安裝分兩種:

  • 編譯安裝。直接去github或gitee去下載官方的發行版,編譯安裝後,將so拓展寫入php.ini檔。
  • 容器安裝。 swoole引擎應用廣泛,所以hub上有很多可用的容器,選擇需要的pull一下即可。

具體操作百度一下即可,網路上相關內容很多。

Swoole引擎的優點

  1. 常駐記憶體。傳統 PHP框架或單文件,在處理每個請求之前,都要做一遍加載框架文件、配置的操作,請求完成之後會釋放所有資源和內存,無須擔心內存洩漏。但如果請求數量上升,並發很高的時候,快速建立資源,又馬上釋放,會導致 PHP 程式運作效率急遽下降。而使用 Swoole 則沒有這個問題:PHP的程式碼載入到記憶體後,擁有更長的生命週期,這樣建立的資料庫連線和其他大的對象,不被釋放。每次請求只需要處理很少的程式碼,而這些程式碼只在第一次執行時,被 PHP 解析器編譯,駐留記憶體。以後都是直接載入 OPCODE ,讓 Zend 引擎直接運作。另外,之前PHP無法實現的,如資料庫連線池,快取連接池都可以在Swoole引擎下實現。系統的運作效率會大大提高。
  2. 快速開發。 Swoole引擎提供了PHP語言的非同步多執行緒伺服器,非同步TCP/UDP網路客戶端,非同步MySQL,非同步Redis,資料庫連線池,AsyncTask,訊息佇列,毫秒定時器,非同步檔案讀寫,非同步DNS查詢。 Swoole內建了Http/WebSocket伺服器端/客戶端、Http2.0伺服器端。
  3. 協程程式設計模式。 Swoole4可以使用完全同步的程式碼實作非同步程式。 PHP程式碼無需額外增加任何關鍵字,底層自動進行協程調度,實現非同步IO。

Swoole引擎的流程解析

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進程

swoole中worker/task進程都是由Manager進程Fork並管理的。

子程序結束執行時,manager程序負責回收此子程序,避免成為殭屍程序。並建立新的子程序
伺服器關閉時,manager程序將發送訊號給所有子程序,通知子程序關閉服務
伺服器reload時,manager程序會逐一關閉/重新啟動子程序

# Worker進程

Swoole提供了完善的進程管理機制,當Worker進程異常退出,如發生PHP的致命錯誤、被其他程式誤殺,或達到max_request次數之後正常退出。主進程會重新拉起新的Worker進程。 Worker進程內可以像普通的apache php或php-fpm寫程式碼。不需要像Node.js那樣寫非同步回呼的程式碼。

各行程的回呼函數

Master內的回呼函數:

    onStart
  • onShutdown

######### #####Worker進程內的回呼函數#########onWorkerStart######onWorkerStop######onConnect######onClose######onReceive# #####onFinish#########TaskWorker進程內的回呼函數###
  • onTask
  • onWorkerStart

Manager程序內的回呼函數

  • onManagerStart
  • onManagerStop

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介面進行通訊。

實際專案中的各行程執行緒的分工:

  • Manager程式:負責管理worker進程,建立或回收
  • Worker進程:遊戲邏輯處理
  • taskWorker進程:向客戶端發送網路套件、關閉長期不活躍的tcp連線

Swoole版本相容性

該專案開發階段使用的swoole引擎版本1.9.6,後來由於測試環境安裝成了4.3.2版本,所以嘗試業務程式碼作調整。不過swoole的向下相容很值得佩服的是,這過程中竟然只發現了一處代碼不相容的問題:是有關swoole_server的一項配置參數,在原來版本採用了魔鬼數字進行配置的,但是到新版本,這個數字沒有被巨集定義,後來透過查看swoole源碼找到了巨集定義組,然後修改了這處組態。 (不過版本升級順利也是基於swoole的業務代碼比較少,所以僅供參考

更多相關學習推薦:swoole教程

以上是分享Swoole引擎原理的快速入門乾貨的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除