加速器架構¶
NextPDF 加速器引擎(Spectrum / Prisma)支援兩種核心部署模式,分別適用於不同的基礎設施場景。本文說明兩種模式的架構設計、通訊機制與故障處理策略。
整體架構¶
flowchart TD
subgraph PHP["PHP 應用程式層"]
APP["應用程式\n(Laravel / Symfony / CLI)"]
CORE["NextPDF Core\nDocumentFactory"]
CLIENT["SpectrumClient\nPSR-18 HTTP Client"]
FFI["FFI 橋接層\n(可選)"]
end
subgraph ModeA["Mode A — Sidecar"]
SIDECAR["nextpdf-spectrum\n(同主機程序)"]
SOCKET["Unix Socket\n/run/nextpdf/spectrum.sock"]
end
subgraph ModeB["Mode B — Remote"]
REMOTE["Prisma 服務\n(獨立容器 / K8s Pod)"]
REST["REST API\nHTTPS / mTLS"]
end
subgraph Fallback["降級層"]
PHP_IMPL["PHP 原生實作\n(自動啟用)"]
end
APP --> CORE
CORE --> CLIENT
CLIENT -->|"Mode A"| SOCKET
CLIENT -->|"Mode B"| REST
SOCKET --> SIDECAR
REST --> REMOTE
CLIENT -->|"斷路器觸發"| PHP_IMPL
CORE -.->|"直接 FFI (可選)"| FFI
FFI -.-> SIDECAR Mode A — Sidecar 程序¶
Sidecar 模式將 nextpdf-spectrum(或 nextpdf-prisma)二進位檔作為獨立程序,在同一主機上與 PHP 應用程式並排執行。PHP 端透過 Unix Domain Socket 或本地 TCP 連接埠與之通訊。
適用場景¶
- 傳統 VPS / 裸機伺服器
- Docker Compose(單機部署)
- Laravel Octane + Roadrunner / Swoole
- 對延遲極度敏感的應用(Unix Socket 延遲 < 0.1 ms)
通訊流程¶
sequenceDiagram
participant PHP as PHP Process
participant Socket as Unix Socket
participant Spectrum as nextpdf-spectrum
PHP->>Socket: connect(/run/nextpdf/spectrum.sock)
PHP->>Socket: POST /v1/font/subset (msgpack 編碼)
Socket->>Spectrum: 轉發請求
Spectrum-->>Socket: 200 OK (二進位 payload)
Socket-->>PHP: 回傳結果
PHP->>PHP: 解碼結果,繼續渲染管線 設定範例¶
# 啟動 Sidecar(建議使用 systemd 管理)
nextpdf-spectrum serve \
--socket /run/nextpdf/spectrum.sock \
--workers $(nproc) \
--mode sidecar
; /etc/systemd/system/nextpdf-spectrum.service
[Unit]
Description=NextPDF Spectrum Sidecar
After=network.target
[Service]
ExecStart=/usr/local/bin/nextpdf-spectrum serve --socket /run/nextpdf/spectrum.sock
Restart=always
User=www-data
Group=www-data
RuntimeDirectory=nextpdf
[Install]
WantedBy=multi-user.target
// PHP 端設定(環境變數方式)
// SPECTRUM_MODE=sidecar
// SPECTRUM_SOCKET=/run/nextpdf/spectrum.sock
// SPECTRUM_TIMEOUT_MS=5000
Mode B — 遠端服務¶
遠端模式將 Prisma 作為獨立 HTTP/gRPC 服務部署,PHP 端透過 PSR-18 HTTP Client 發送 REST 請求。這是 Kubernetes 及微服務架構的標準部署方式。
適用場景¶
- Kubernetes 叢集(Prisma 以 Deployment / StatefulSet 形式運行)
- 多 PHP 實例共享單一 Prisma 服務
- 需要獨立擴展加速器資源的場景
- 企業級 mTLS 雙向驗證需求
通訊流程¶
sequenceDiagram
participant PHP as PHP (SpectrumClient)
participant LB as Load Balancer
participant Prisma1 as Prisma Pod 1
participant Prisma2 as Prisma Pod 2
PHP->>LB: POST /v1/embed (HTTPS + Bearer JWT)
LB->>Prisma1: 轉發(一致性雜湊)
Prisma1-->>LB: 200 OK
LB-->>PHP: 回傳向量化結果
Note over PHP,Prisma2: 斷路器開路時自動切換
PHP->>LB: POST /v1/parse (重試 #2)
LB->>Prisma2: 轉發至健康節點
Prisma2-->>LB: 200 OK
LB-->>PHP: 回傳解析結果 Kubernetes 部署片段¶
# prisma-deployment.yaml(Enterprise 示範)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nextpdf-prisma
namespace: nextpdf-system
spec:
replicas: 3
selector:
matchLabels:
app: nextpdf-prisma
template:
metadata:
labels:
app: nextpdf-prisma
spec:
containers:
- name: prisma
image: ghcr.io/nextpdf-labs/prisma-enterprise:latest
ports:
- containerPort: 8080
env:
- name: PRISMA_MODE
value: remote
- name: PRISMA_WORKERS
value: "4"
resources:
requests:
cpu: "2"
memory: "2Gi"
limits:
cpu: "4"
memory: "4Gi"
電路斷路器(Circuit Breaker)¶
SpectrumClient 內建電路斷路器,確保加速器不可用時應用程式能優雅降級。
狀態機¶
stateDiagram-v2
[*] --> Closed: 初始狀態
Closed --> Open: 連續失敗 ≥ threshold (預設 3)
Open --> HalfOpen: 冷卻期結束 (預設 30s)
HalfOpen --> Closed: 探測請求成功
HalfOpen --> Open: 探測請求失敗 降級行為¶
| 操作 | Spectrum 不可用時降級為 |
|---|---|
| 字型子集化 | PHP 原生 FontSubsetter |
| 影像壓縮 | PHP GD / Imagick |
| PDF 解析 | PHP 串流解析器 |
| 文字提取 | PHP XPDF 橋接(若已安裝) |
| 向量嵌入 | 不可用(拋出 AcceleratorUnavailableException) |
// 設定斷路器閾值
use NextPDF\Accelerator\SpectrumClient;
use NextPDF\Accelerator\CircuitBreakerConfig;
$client = new SpectrumClient(
config: new CircuitBreakerConfig(
threshold: 3,
cooldownSeconds: 30,
halfOpenProbeTimeout: 5,
),
);
模式選擇指引¶
| 考量因素 | Mode A (Sidecar) | Mode B (Remote) |
|---|---|---|
| 延遲 | 極低(< 0.5 ms Unix Socket) | 低(1-5 ms 本地網路) |
| 擴展性 | 與 PHP 程序一對一 | 獨立水平擴展 |
| 運維複雜度 | 低(systemd 管理) | 中(K8s 管理) |
| 資源共享 | 無法跨 PHP 實例共享 | 多 PHP 實例共享 |
| mTLS 支援 | 否(本地信任) | 是(Enterprise) |
| 推薦情境 | 傳統伺服器、Octane | K8s、微服務、多租戶 |