針對workerman 聊天室架設在 nginx 的 php8.5-cli 中 php.ini 的最佳化

回覆文章
Brave Ye
系統管理員
文章: 5547
註冊時間: 2025-11-08, 13:32
聯繫:

針對workerman 聊天室架設在 nginx 的 php8.5-cli 中 php.ini 的最佳化

文章 Brave Ye »

​針對 Workerman 這種常駐記憶體 (Resident Memory) 的架構,PHP 8.5 CLI 的最佳化重點在於啟用 OPcache 與 JIT(即時編譯)、防止記憶體洩漏,以及強化底層連線處理能力
以下是針對 php8.5-cli 下 php.ini 的核心最佳化配置:

​1. 啟用 OPcache 與 JIT (極大幅提升效能)
PHP 預設在 CLI 模式下是關閉 OPcache 的,這會導致 Workerman 每次啟動或動態載入檔案時都重新編譯 PHP 腳本。在 PHP 8.5 中,開啟 CLI 的 OPcache 並配合 JIT,可以顯著降低 CPU 負載與 WebSocket 訊息處理的延遲。

代碼: 選擇全部

[opcache]
; 必須設定為 1 才能在 CLI 模式下啟用
opcache.enable_cli=1
; 分配給 OPcache 的共享記憶體 (依主機記憶體調整,128M 通常夠用)
opcache.memory_consumption=128
; 儲存內部字串的記憶體大小,減少記憶體重覆佔用
opcache.interned_strings_buffer=16
; 快取檔案數量上限
opcache.max_accelerated_files=10000
; 每次檢查檔案更新的時間 (生產環境可設為 0,完全依賴手動 reload)
opcache.revalidate_freq=0

; PHP 8 之後的核心 JIT 設定
opcache.jit_buffer_size=128M
; 使用 tracing 模式,針對頻繁執行的程式碼路徑進行編譯最佳化
opcache.jit=tracing
2. 記憶體與執行時間限制
Workerman 是長時間運作的進程,每個 Worker 進程會維持自己的記憶體池。需要確保進程不會因為時間限制被終止,並設定合理的記憶體上限以防業務邏輯造成的記憶體洩漏 (Memory Leak) 拖垮整台伺服器。

代碼: 選擇全部

; CLI 預設為 0 (無限制),確保強制設定為 0 以防被意外中斷
max_execution_time=0
; 關閉輸入時間限制
max_input_time=-1
; 單一 Worker 進程的記憶體上限 (建議 256M 或 512M,超過此限制 PHP 會自動重啟該 Worker)
memory_limit=256M
3. 啟用垃圾回收機制 (Garbage Collection)
長時間運行的 PHP 進程極度依賴 GC 來清理循環參照的變數。

代碼: 選擇全部

; 確保垃圾回收為開啟狀態 (通常預設為 On)
zend.enable_gc=On
4. 網路與 Socket 連線微調
聊天室維持大量持久連線,需配合 Workerman 自身的應用層心跳 (Heartbeat) 機制,調整底層 Socket 超時。

代碼: 選擇全部

; 底層 socket 超時時間 (秒),建議與 Workerman 業務邏輯的心跳檢測時間相符或稍長
default_socket_timeout=60
5. 日誌與錯誤處理 (生產環境)
常駐進程的錯誤若直接輸出在終端機,容易造成緩衝區阻塞或干擾運行,必須將錯誤導向實體日誌檔。

代碼: 選擇全部

; 關閉終端機錯誤輸出
display_errors=Off
display_startup_errors=Off
; 記錄錯誤到檔案
log_errors=On
; 指定明確的日誌路徑,方便透過 fail2ban 或 elk 監控
error_log=/var/log/workerman-php-error.log
; 記錄所有錯誤 (包含 Warning/Notice,有助於抓出常駐環境下不易察覺的 Bug)
error_reporting=E_ALL
超越 php.ini 的關鍵效能擴展 (Event 擴展)
光改 php.ini 還不夠,PHP 核心預設使用 select 系統呼叫來處理網路 I/O,這在併發超過數千時效能極差。
請務必為 PHP 8.5 安裝並啟用 event 擴展(或 ev 擴展)。安裝後,Workerman 會自動偵測並切換到底層的 epoll 事件輪詢機制,這是讓 PHP 聊天室能撐起單機數萬甚至十萬級別併發的真正關鍵。
​一、 安裝前置依賴套件
​event 擴展編譯時需要系統層級的 libevent 開發庫以及 PHP 8.5 的開發標頭檔 (php-dev 或 php-devel)。

代碼: 選擇全部

sudo apt update
# 1. 安裝 PHP 8.5 的開發工具套件
sudo apt install -y php8.5-dev php-peer build-essential libevent-dev

# 2. 重新執行 PECL 安裝指令
sudo pecl -d php_suffix=8.5 install event

三、 在 php.ini 中啟用擴展
php --ini
通常在 Debian/Ubuntu 為 /etc/php/8.5/cli/php.ini
或/etc/php/8.5/cli/conf.d/
2 注意擴展載入順序(關鍵步驟):
event 擴展必須在 sockets 擴展之後載入,否則啟動時會報錯。

方式 B:透過獨立配置文件載入(Debian/Ubuntu 推薦):
在 /etc/php/8.5/cli/conf.d/ 目錄下建立一個數字較大的配置文件(確保比 sockets 後載入):

代碼: 選擇全部

echo "extension=event.so" | sudo tee /etc/php/8.5/cli/conf.d/30-event.ini
sudo phpenmod -v 8.5 sockets
sudo phpenmod -v 8.5 event
四、 驗證安裝與 Workerman 驅動測試
1檢查 PHP CLI 是否順利載入 event 模組:
php -m | grep event
如果輸出 event,代表擴展已成功安裝並啟動。
2驗證 Workerman 是否已自動切換至 Event 驅動:
編寫一個簡單的 Workerman 啟動腳本,或在您的聊天室主程式入口處執行:

代碼: 選擇全部

<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;

// 檢查目前 Workerman 選用的事件驅動核心
echo "Current Event Loop: " . Worker::$eventLoopClass . "\n";
​預期結果:
若成功啟用,終端機將會顯示:
Current Event Loop: Workerman\Events\Event
(如果顯示 Workerman\Events\Select,則代表 event 擴展未成功啟用或載入順序有誤)。
五、 排錯技巧 (Troubleshooting)
​錯誤訊息:PHP Warning: PHP Startup: Unable to load dynamic library 'event.so' - undefined symbol: ...
​原因: event 比 sockets 先載入,或編譯時未開啟 socket 支援。
​解決方法: 請檢查 php.ini 或 conf.d/ 中的檔案命名順序,務必確保 extension=sockets 先於 extension=event.so 載入。
設定完 Event 擴展後,您可能還會需 要

優化 Linux 系統的最大連線數限制(ulimit/sysctl)
https://share.gemini.google/QgdTJLVvZs9K
回覆文章

誰在線上

正在瀏覽這個版面的使用者:沒有註冊會員 和 0 位訪客