跳到內容

NextPDF Gotenberg 的生產環境使用方式

這個橋接器是一趟同步的 HTTP 往返,外層包覆著驗證。它不會重試、排隊、快取,也不會限流。這些行為應由橋接器外圍的應用程式負責。本頁說明這些行為各自該放在哪裡,以及橋接器提供哪些保證,讓你能正確建構其餘部分。

請把每一次轉換都視為對某個服務發出的遠端呼叫——這個服務由你營運,但並非在你的行程內受你掌控。請針對它的延遲與失敗進行設計。

GotenbergConfig 保存 API URL,並在啟用驗證時保存一組 bearer token。token 欄位標註了 #[\SensitiveParameter],因此會在堆疊追蹤中被遮蔽。但它的來源仍由你負責。

  • 在行程啟動時,從你的機密管理器或注入的環境值取得 token。不要把它提交進版控,也不要放進隨映像檔一起發布的設定檔。
  • 每個請求範圍或每個 worker 只建立一次設定,不要在每次轉換時重新建立。它是不可變的,持有成本也很低。
  • GotenbergConfig::fromArray() 在設計上容許格式不正確的輸入:它會默默以預設值替代。在生產環境中,呼叫 fromArray() 之前,請自行驗證來源陣列。如此一來,缺少 URL 會在你的啟動流程中以設定錯誤的形式浮現,而不是稍後在每次轉換時才丟出 Invalid Gotenberg configuration: apiUrl is empty 例外。

timeout(單位為秒,預設 30)是硬性的傳輸逾時,由鎖定 cURL 的傳輸層套用。透過 LibreOffice 進行的 Office 轉換不會瞬間完成;大型或複雜的文件需要更長時間。請根據真實文件實測出的轉換延遲設定逾時,並保留一些餘裕。請讓它低於任何上游閘道或 PHP 的 max_execution_time。這樣橋接器會先逾時,而你會得到具型別的例外,而不是遭到強制終止的行程。

若你依賴注入的 PSR-18 用戶端路徑(未注入 responseFactory,或使用無 pin 的純 IP URL),橋接器並不會把 timeout 值套用到該用戶端上。也請在 PSR-18 用戶端本身設定逾時,讓兩條傳輸路徑都有上限。

橋接器每次呼叫只會發出一次請求,並且絕不重試。請在呼叫端加入重試邏輯,並確保其安全:

  • 只在傳輸層失敗(成因為 PSR-18 用戶端例外的 GotenbergConvertException)以及具冪等性的伺服器錯誤(HTTP 502503504)時才重試。不要不分情況地對每一個 GotenbergConvertException 都重試。400 類的回應通常代表輸入有誤,重試也會以同樣方式失敗。
  • 請使用帶有抖動(jitter)且有上限的指數退避。負載過重的轉換服務會回傳 503;持續猛打它只會讓停機更嚴重。
  • 為總嘗試次數與總牆鐘時間設定上限。轉換本來就慢,因此沒有上限的重試會讓尾端延遲倍增。
  • 重新驗證是自動進行的:每一次重試的呼叫都會重新執行 URL 驗證與位址重新檢查,因此重試無法意外繞過 SSRF 防護。

在請求進行期間,每一次轉換都會在 Gotenberg 端佔用一條連線與一個 LibreOffice worker。橋接器本身是無狀態的,可安全地讓多個 worker 並行使用。然而,Gotenberg 服務的轉換容量是有限的。

  • 請從你這一端(透過佇列、號誌或 worker 池)限制進行中的轉換數量,使其不超過 Gotenberg 所能承受的容量。容量規劃是你的 Gotenberg 部署特性,而非本套件特性——請參見 /integrations/gotenberg/security-and-operations/.
  • 輸入大小上限(maxFileSize,預設 50 MiB)是橋接器唯一內建的資源上限。它會在請求送出之前於行程內強制執行,因此過大的檔案絕不會消耗服務容量。請將它調低到符合你文件實際所需的程度;相較於較大的上限,較小的上限是更便宜的拒絕服務防護手段。
  • 沒有行程內快取。若同一份文件會被反覆轉換,請在你的應用程式中以輸入內容的雜湊值為鍵,快取產出的 PDF。

注入一個 PSR-3 記錄器,即可在每次轉換請求時取得一筆 debug 記錄。該記錄包含請求 URL、檔名、偵測到的格式,以及請求內容長度。它不會包含檔案內容或 bearer token。

  • 將該訊號提升為指標:依格式與結果統計轉換次數,並把每次 convertFile() / convertString() 呼叫前後的牆鐘時間記錄為延遲直方圖。橋接器本身並不發出指標。
  • 結果物件會暴露一個 renderTimeMs 欄位,除非你的整合自行量測並設定它,否則它會是 0.0;橋接器並不會從 Gotenberg 的回應填入它。若你需要這個數字,請自行為該呼叫計時。
  • 記錄例外時,請連同其型別一併記錄。例外型別是判斷失敗位置的主要訊號;完整清單收錄於 /integrations/gotenberg/troubleshooting/.
  • 請從你的就緒(readiness)或健康(health)端點探測 isAvailable(),而不是在每次轉換時探測。它是一個發往 /healthHEAD 請求。在每次轉換前都執行它,只會讓你對該服務的請求速率倍增,卻毫無益處。

橋接器會以具型別的例外呈現失敗,並且絕不回傳不完整或未經驗證的結果。相關保證如下:

  • 200 的狀態碼、Content-Type 不含 application/pdf,或開頭不是 %PDF 的內文,各自都會引發 GotenbergConvertException。只有在這三項檢查全部通過時,才會回傳結果物件。
  • PSR-18 用戶端的失敗(包含網路失敗或逾時)會被包裝為 GotenbergConvertException,以原始例外作為其成因,並以用戶端的代碼作為例外代碼。
  • 驗證失敗(非 HTTPS 的 URL、private/reserved 位址、過大的輸入、不安全的檔名)會在任何網路流量之前引發 RuntimeException
  • 無法辨識的副檔名會在任何網路流量之前引發 ValueError

請捕捉這些具體型別。examples/convert-office-to-pdf.php 中的範例程式展示了完整的捕捉順序。/integrations/gotenberg/troubleshooting/ 說明了每一個觸發情境。

橋接器產出一份 PDF 之後就會停止。一個常見的生產流程是:

  1. 使用這個橋接器轉換 Office 文件。
  2. 將產出的位元組載入一份 NextPDF 文件。
  3. 套用後處理——頁面組合、浮水印、PDF/A 轉換、數位簽章。

第 3 步是 NextPDF 的職責,而非橋接器的職責。簽署、PDF/A profile 與浮水印由 nextpdf/premium 提供。請將轉換與後處理保持為各自獨立的階段,如此一來,轉換失敗與簽署失敗便能分開診斷。

Pro 版的 PAdES 支援僅限於 B-B 基準。它並不提供 B-T、B-LT 或 B-LTA,而且這些 profile 並不會因為透過這個橋接器轉換文件而被隱含包含。長期驗證的能力屬於另一個版本層級的議題,並不在本套件的範圍之內。

  • /integrations/gotenberg/configuration/ — 傳輸選擇規則與 pin 模型。
  • /integrations/gotenberg/security-and-operations/ — 部署並強化 Gotenberg 相依套件。
  • /integrations/gotenberg/troubleshooting/ — 例外清單。
  • /integrations/gotenberg/integration/ — 將轉換後的 PDF 接入 NextPDF 流程。