跳轉到

加速器架構

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、微服務、多租戶

參見