Laravel 12 WebSocket (Reverb) 容器化全攻略:Nginx 反向代理實戰
1. 目標 (Objective)
在 Laravel 12 中,官方推出了由 PHP 原生驅動的極速 WebSocket 伺服器 —— Reverb。但在容器化環境下,如何協調 Nginx、PHP-FPM 與 Reverb 之間的流量轉發,是開發者面臨的首要挑戰。
本文旨在建立一套穩定的 Docker 化架構,透過 Nginx 統一入口,實現 HTTP (PHP-FPM) 與 WS (Reverb) 的精準分流,並確保在高併發連線下的穩定性。
2. 技術亮點 (Technical Highlights)
PHP 8.4 常駐監聽:利用 PHP 8.4 的非阻塞特性,讓 Reverb 處理萬級併發連線。
Nginx 協議升級 (101 Switching Protocols):精確配置
Upgrade標頭,實現從 HTTP 到 WebSocket 的無縫切換。服務解耦:將 Web 應用與 WebSocket 伺服器拆分為獨立容器,提升系統可擴展性。
pcntl 併發控制:在 Dockerfile 中強化進程管理擴充,確保 Reverb 具備處理多工任務的能力。
3. 架構圖描述 (Architecture Diagram)
Nginx 作為反向代理,根據 URL 路徑將請求分發至不同的容器:
[ Client Browser ]
│
▼ (Port 80 / 443)
[ Nginx (Reverse Proxy) ]
│
├─── [ / ] ──▶ (FastCGI) ──▶ [ App Container (PHP 8.4-FPM) ]
│
└─── [ /app ] ── (WS) ───▶ [ Reverb Container (Port 8080) ]
4. Nginx 配置:關鍵的協議升級
在 nginx/default.conf 中,必須特別處理 Reverb 的專屬路徑。請注意,Reverb 預設使用 /app 作為連接端點。
server {
listen 80;
server_name localhost;
root /var/www/html/public;
index index.php;
# WebSocket 核心轉發邏輯
location /app {
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 必須包含以下兩行以實現 WebSocket 握手
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_read_timeout 86400s; # 避免長連線因逾時中斷
proxy_pass http://reverb:8080;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass app:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
5. Docker 編排實戰 (docker-compose.yml)
我們使用同一個 PHP 8.4 鏡像來啟動兩個不同的服務:一個負責處理 Web 請求,另一個負責 Reverb 守護進程。
services:
app:
build: .
container_name: laravel-app
volumes:
- .:/var/www/html
depends_on:
- redis
reverb:
build: .
container_name: laravel-reverb
# 核心指令:啟動 Reverb 並監聽所有網路介面
command: php artisan reverb:start --host=0.0.0.0 --port=8080
volumes:
- .:/var/www/html
depends_on:
- app
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- .:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- reverb
6. 流程圖描述 (Flowchart)
事件觸發:Laravel 後端觸發
MessageSent事件。佇列分發:事件被推送到 Redis 佇列(建議生產環境必備)。
廣播推播:Reverb 容器 監聽到事件,透過 WebSocket 持久連線將資料推至前端。
前端接收:瀏覽器端的 Laravel Echo 接收資料,透過 Vue 3 響應式更新介面。
7. 重要排錯與優化 (Troubleshooting)
PHP 8.4 擴充要求:
確保 Dockerfile 中包含 pcntl。Reverb 依賴此擴充來管理進程訊號與併發處理。
DockerfileRUN docker-php-ext-install pcntl bcmath pdo_mysql環境變數對齊:
在 .env 中,VITE_REVERB_HOST 應設定為用戶瀏覽器可存取的位址(如 localhost),而 REVERB_HOST(後端通訊用)則應設定為容器名稱 reverb。
Queue Worker 運作:
若前端遲遲收不到訊息,請確認是否有容器正在執行 php artisan queue:work。
8. 結論 (Conclusion)
透過 Laravel 12 Reverb 與 Docker 的整合,我們徹底擺脫了對 Pusher 或第三方服務的依賴,實現了真正的「即時通訊自主」。這套架構不僅部署簡單,且在 Nginx 的反向代理下,具備了極佳的安全性與效能表現。
沒有留言:
張貼留言