PHP-FPM vs Swoole

chenos發表於2018-04-07

前幾天看見有幾篇講 swoole 的文章,今天我也來湊個熱鬧。水平有限,細節理解可能不到位,歡迎大家幫我補充、糾正。

PHP-FPM

早期版本的 PHP 並沒有內建的 WEB 伺服器,而是提供了 SAPI(Server API)給第三方做對接。現在非常流行的 php-fpm 就是通過 FastCGI 協議來處理 PHP 與第三方 WEB 伺服器之間的通訊。比如 Nginx + php-fpm 的組合,這種方式執行的 fpm 是 Master/Worker 模式,啟動一個 Master 程式監聽來自 Nginx 的請求,再 fork 多個 Worker 程式處理請求。每個 Worker 程式只能處理一個請求,單一程式的生命週期大體如下:

  1. 初始化模組。
  2. 初始化請求。此處請求是請求 PHP 執行程式碼的意思,並非 HTTP 的請求。
  3. 執行 PHP 指令碼。
  4. 結束請求。
  5. 關閉模組。

對細節感興趣的可以點這裡看圖

多程式模型是依賴程式數來解決併發問題,一個程式只能處理一個連線,當啟動大量程式,程式排程消耗可能佔 CPU 的百分之幾十甚至 100%,比如 C10K 問題,多程式模型就力不從心了。

Swoole

Swoole 採用的也是 Master/Worker 模式,不同的是 Master 程式有多個 Reactor 執行緒,Master 只是一個事件發生器,負責監聽 Socket 控制程式碼的事件變化。Worker 以多程式的方式執行,接收來自 Reactor 執行緒的請求,並執行回撥函式(PHP 編寫的)。啟動 Master 程式的流程大致是:

  1. 初始化模組。
  2. 初始化請求。因為 swoole 需要通過 cli 的方式執行,所以初始化請求時,不會初始化 PHP 的全域性變數,如 $_SERVER, $_POST, $_GET 等。
  3. 執行 PHP 指令碼。包括詞法、語法分析,變數、函式、類的初始化等,Master 進入監聽狀態,並不會結束程式。

Swoole 加速的原理

  • 由 Reactor(epoll 的 IO 複用方式)負責監聽 Socket 控制程式碼的事件變化,解決高併發問題。
  • 通過記憶體常駐的方式節省 PHP 程式碼初始化的時間,在使用笨重的框架時,用 swoole 加速效果是非常明顯的。

對比不同

PHP-FPM

  • Master 主程式 / Worker 多程式模式。
  • 啟動 Master,通過 FastCGI 協議監聽來自 Nginx 傳輸的請求。
  • 每個 Worker 程式只對應一個連線,用於執行完整的 PHP 程式碼。
  • PHP 程式碼執行完畢,佔用的記憶體會全部銷燬,下一次請求需要重新再進行初始化等各種繁瑣的操作。
  • 只用於 HTTP Server。

Swoole

  • Master 主程式(由多個 Reactor執行緒組成)/ Worker 多程式(或多執行緒)模式
  • 啟動 Master,初始化 PHP 程式碼,由 Reactor 監聽 Socket 控制程式碼的事件變化。
  • Reactor 主執行緒負責子多執行緒的均衡問題,Manager 程式管理 Worker 多程式,包括 TaskWorker 的程式。
  • 每個 Worker 接受來自 Reactor 的請求,只需要執行回撥函式部分的 PHP 程式碼。
  • 只在 Master 啟動時執行一遍 PHP 初始化程式碼,Master 進入監聽狀態,並不會結束程式。
  • 不僅可以用於 HTTP Server,還可以建立 TCP 連線、WebSocket 連線。

以上主要針對核心執行機制作對比,列舉的不同,暫時就想到這幾點了,如果有漏掉的重點,歡迎大家幫我補充啦~

相關文章