Gotenberg vs IronPDF:技術比較指南
當.NET開發人員評估 PDF 產生解決方案時,Gotenberg 脫穎而出,它是一個基於 Docker 的微服務,透過 REST API 呼叫將 HTML 轉換為 PDF。 雖然 哥登堡 能夠適應各種不同的架構,但它也帶來了顯著的基礎設施開銷——Docker 容器、網路延遲和操作複雜性。 IronPDF提供了一個替代方案:一個進程內NuGet包,提供相同的基於 Chromium 的渲染,而無需容器、網路呼叫或基礎架構管理。
本次比較從技術相關維度對兩種解決方案進行了考察,以幫助專業開發人員和架構師根據其.NET PDF 需求做出明智的決策。
了解哥登堡
Gotenberg 是一個基於 Docker 的微服務架構,用於產生 PDF 檔案。 它作為一個獨立的容器運行,提供 REST API 端點,用於將 HTML、URL 和其他格式轉換為 PDF。 每次 PDF 操作都需要向 哥登堡 服務發起 HTTP 呼叫。
Gotenberg 使用 POST /forms/chromium/convert/html 等端點進行 HTML 到 PDF 的轉換,使用 POST /forms/chromium/convert/url 等端點進行 URL 到 PDF 的轉換。 配置透過 multipart/form-data 傳遞,參數基於字串,例如 marginTop 和 marginBottom(以英吋為單位)。 該服務需要 Docker 部署、容器編排(Kubernetes/Docker Compose)和網路基礎架構。
此架構需要: Docker容器部署和管理
- 每次 PDF 請求都需要網路通訊(延遲 10-100 毫秒以上)
- 容器冷啟動處理(首次請求需要 2-5 秒)
- 健康檢查端點和服務監控
- 為每個請求建立 multipart/form-data 格式
了解IronPDF
IronPDF是一個原生.NET函式庫,它以NuGet套件的形式在流程內運作。 它提供基於 Chromium 的 HTML 渲染,無需外部服務、網頁呼叫或容器基礎設施。
IronPDF使用 ChromePdfRenderer 作為其主要渲染類,並具有 RenderHtmlAsPdf() 和 RenderUrlAsPdf() 等方法。 配置使用類型化的 C# 屬性,包括 RenderingOptions,包括 MarginBottom(以毫米為單位)。 文件以 SaveAs() 儲存,或以 BinaryData 存取。
此圖書館僅需:
- NuGet套件安裝 (
dotnet add package IronPdf) - 許可證密鑰配置
- 標準.NET專案設定
架構和基礎設施比較
這些解決方案之間的根本區別在於它們的部署和運行時架構。
| 因素 | 哥登堡 | IronPDF |
|---|---|---|
| 部署 | Docker容器+編排 | 單一NuGet包 |
| 建築學 | 微服務(REST API) | 行程內庫 |
| 每次請求的延遲 | 10-100毫秒以上(網路往返時間) | 開銷小於 1 毫秒 |
| 冷啟動 | 2-5秒(容器初始化) | 1-2秒(僅限首次渲染) |
| 基礎設施 | Docker、Kubernetes、負載平衡器 | 無需 |
| 網路依賴性 | 必需的 | 沒有任何 |
| 故障模式 | 網路、容器、服務故障 | 標準.NET異常 |
| API 風格 | REST multipart/form-data | 原生 C# 方法調用 |
| 規模化 | 水平方向(更多容器) | 垂直(進行中) |
| 偵錯 | 分散式追蹤 | 標準偵錯工具 |
| 記憶體管理 | 獨立容器(512MB-2GB) | 共享應用程式內存 |
| 版本控制 | 容器圖像標籤 | NuGet套件版本 |
| 健康檢查 | 需要 HTTP 端點 | 暫不需要(進行中) |
| CI/CD 的複雜性 | 容器構建,註冊表推送 | 標準.NET構建 |
哥登堡基於 Docker 的方法需要容器部署、健康監控和網路基礎設施管理。 IronPDF透過進程內運作完全消除了這個基礎架構層。
程式碼比較:常見 PDF 操作
基本的 HTML 轉 PDF 轉換
最基本的操作清楚地反映了架構上的差異。
哥德堡:
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;
class GotenbergExample
{
static async Task Main()
{
var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html";
using var client = new HttpClient();
using var content = new MultipartFormDataContent();
var html = "<html><body><h1>Hello from Gotenberg</h1></body></html>";
content.Add(new StringContent(html), "files", "index.html");
var response = await client.PostAsync(gotenbergUrl, content);
var pdfBytes = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("output.pdf", pdfBytes);
Console.WriteLine("PDF generated successfully");
}
}using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;
class GotenbergExample
{
static async Task Main()
{
var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html";
using var client = new HttpClient();
using var content = new MultipartFormDataContent();
var html = "<html><body><h1>Hello from Gotenberg</h1></body></html>";
content.Add(new StringContent(html), "files", "index.html");
var response = await client.PostAsync(gotenbergUrl, content);
var pdfBytes = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("output.pdf", pdfBytes);
Console.WriteLine("PDF generated successfully");
}
}IronPDF:
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class IronPdfExample
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var html = "<html><body><h1>Hello from IronPDF</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF generated successfully");
}
}// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class IronPdfExample
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var html = "<html><body><h1>Hello from IronPDF</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF generated successfully");
}
}Gotenberg 需要建立一個 HttpClient,建構 MultipartFormDataContent,將 HTML 新增為具有特定檔案名稱的檔案附件 (index.html),向 哥登堡 服務端點發出非同步 HTTP POST 請求,以讀取回應位元組,然後寫入回應。 每個請求都會透過網路傳輸,因此都會存在延遲和故障模式。
IronPDF建立 ChromePdfRenderer,使用 HTML 字串呼叫 RenderHtmlAsPdf(),並使用 SaveAs() 儲存。 該操作是同步的、進程內操作,並且使用類型化方法而不是基於字串的表單資料。
如需了解進階 HTML 渲染選項,請參閱HTML 轉 PDF 轉換指南。
URL 轉 PDF
將即時網頁轉換為 PDF 時,會展現出類似的架構模式。
哥德堡:
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;
class GotenbergUrlToPdf
{
static async Task Main()
{
var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/url";
using var client = new HttpClient();
using var content = new MultipartFormDataContent();
content.Add(new StringContent("https://example.com"), "url");
var response = await client.PostAsync(gotenbergUrl, content);
var pdfBytes = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("webpage.pdf", pdfBytes);
Console.WriteLine("PDF from URL generated successfully");
}
}using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;
class GotenbergUrlToPdf
{
static async Task Main()
{
var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/url";
using var client = new HttpClient();
using var content = new MultipartFormDataContent();
content.Add(new StringContent("https://example.com"), "url");
var response = await client.PostAsync(gotenbergUrl, content);
var pdfBytes = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("webpage.pdf", pdfBytes);
Console.WriteLine("PDF from URL generated successfully");
}
}IronPDF:
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class IronPdfUrlToPdf
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("webpage.pdf");
Console.WriteLine("PDF from URL generated successfully");
}
}// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class IronPdfUrlToPdf
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("webpage.pdf");
Console.WriteLine("PDF from URL generated successfully");
}
}Gotenberg 使用 /forms/chromium/convert/url 端點,並將 URL 作為表單資料傳遞。 IronPDF直接使用 URL 字串呼叫 RenderUrlAsPdf()——一個方法呼叫取代了 HTTP 基礎架構。
自訂頁面尺寸和邊距
配置處理揭示了 API 設計上的差異。
哥德堡:
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;
class GotenbergCustomSize
{
static async Task Main()
{
var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html";
using var client = new HttpClient();
using var content = new MultipartFormDataContent();
var html = "<html><body><h1>Custom Size PDF</h1></body></html>";
content.Add(new StringContent(html), "files", "index.html");
content.Add(new StringContent("8.5"), "paperWidth");
content.Add(new StringContent("11"), "paperHeight");
content.Add(new StringContent("0.5"), "marginTop");
content.Add(new StringContent("0.5"), "marginBottom");
var response = await client.PostAsync(gotenbergUrl, content);
var pdfBytes = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("custom-size.pdf", pdfBytes);
Console.WriteLine("Custom size PDF generated successfully");
}
}using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;
class GotenbergCustomSize
{
static async Task Main()
{
var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html";
using var client = new HttpClient();
using var content = new MultipartFormDataContent();
var html = "<html><body><h1>Custom Size PDF</h1></body></html>";
content.Add(new StringContent(html), "files", "index.html");
content.Add(new StringContent("8.5"), "paperWidth");
content.Add(new StringContent("11"), "paperHeight");
content.Add(new StringContent("0.5"), "marginTop");
content.Add(new StringContent("0.5"), "marginBottom");
var response = await client.PostAsync(gotenbergUrl, content);
var pdfBytes = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("custom-size.pdf", pdfBytes);
Console.WriteLine("Custom size PDF generated successfully");
}
}IronPDF:
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
using IronPdf.Rendering;
class IronPdfCustomSize
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
renderer.RenderingOptions.MarginTop = 50;
renderer.RenderingOptions.MarginBottom = 50;
var html = "<html><body><h1>Custom Size PDF</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("custom-size.pdf");
Console.WriteLine("Custom size PDF generated successfully");
}
}// NuGet: Install-Package IronPdf
using System;
using IronPdf;
using IronPdf.Rendering;
class IronPdfCustomSize
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
renderer.RenderingOptions.MarginTop = 50;
renderer.RenderingOptions.MarginBottom = 50;
var html = "<html><body><h1>Custom Size PDF</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("custom-size.pdf");
Console.WriteLine("Custom size PDF generated successfully");
}
}Gotenberg 使用字串參數("0.5")加入 multipart 表單資料中。 紙張尺寸單位為英吋。 每個參數都是一個單獨的 Add() 調用,沒有類型檢查或 IntelliSense 支援。
IronPDF在 RenderingOptions 上使用類型化屬性。 PaperSize 接受一個枚舉值(PdfPaperSize.Letter),邊距是以毫米為單位的數值。 類型化 API 提供編譯時檢查和 IDE 支援。
了解更多關於渲染配置的信息,請參閱IronPDF教學。
API對應參考
對於正在評估 哥登堡 遷移或比較功能的開發人員來說,此對應顯示了等效操作:
端點到方法映射
| 哥德堡路線 | IronPDF當量 |
|---|---|
POST /forms/chromium/convert/html | ChromePdfRenderer.RenderHtmlAsPdf() |
POST /forms/chromium/convert/url | ChromePdfRenderer.RenderUrlAsPdf() |
POST /forms/chromium/convert/markdown | 首先將 Markdown 渲染為 HTML |
POST /forms/pdfengines/merge | PdfDocument.Merge() |
POST /forms/pdfengines/metadata/read | pdf.MetaData |
POST /forms/pdfengines/metadata/write | pdf.MetaData.Author = "..." |
GET /health | 不適用 |
表單參數到渲染選項的映射
| 哥登堡參數 | IronPDF屬性 | 轉換票據 |
|---|---|---|
paperWidth(英吋) | RenderingOptions.SetCustomPaperSizeInInches() | 使用自訂方法 |
paperHeight(英吋) | RenderingOptions.SetCustomPaperSizeInInches() | 使用自訂方法 |
marginTop(英吋) | RenderingOptions.MarginTop | 乘以 25.4 得到毫米 |
marginBottom(英吋) | RenderingOptions.MarginBottom | 乘以 25.4 得到毫米 |
marginLeft(英吋) | RenderingOptions.MarginLeft | 乘以 25.4 得到毫米 |
marginRight(英吋) | RenderingOptions.MarginRight | 乘以 25.4 得到毫米 |
printBackground | RenderingOptions.PrintHtmlBackgrounds | 布林值 |
landscape | RenderingOptions.PaperOrientation | Landscape枚舉 |
scale | RenderingOptions.Zoom | 百分比(100 = 1.0) |
waitDelay | RenderingOptions.RenderDelay | 轉換為毫秒 |
emulatedMediaType | RenderingOptions.CssMediaType | Screen 或 Print |
請注意單位換算:Gotenberg 使用英吋作為頁邊距(例如,"0.5" = 0.5 英吋 = 12.7 毫米),而IronPDF使用毫米。
基礎設施比較
哥登堡 Docker Compose
哥登堡需要容器基礎設施:
# 哥登堡 requires container management
version: '3.8'
services:
app:
depends_on:
- gotenberg
environment:
- GOTENBERG_URL=http://gotenberg:3000
gotenberg:
image: gotenberg/gotenberg:8
ports:
- "3000:3000"
deploy:
resources:
limits:
memory: 2G
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s# 哥登堡 requires container management
version: '3.8'
services:
app:
depends_on:
- gotenberg
environment:
- GOTENBERG_URL=http://gotenberg:3000
gotenberg:
image: gotenberg/gotenberg:8
ports:
- "3000:3000"
deploy:
resources:
limits:
memory: 2G
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30sIronPDF配置
IronPDF不需要任何額外服務:
# IronPDF - No additional services needed
version: '3.8'
services:
app:
environment:
- IRONPDF_LICENSE_KEY=${IRONPDF_LICENSE_KEY}
# No 哥登堡 service. No health checks. No resource limits.# IronPDF - No additional services needed
version: '3.8'
services:
app:
environment:
- IRONPDF_LICENSE_KEY=${IRONPDF_LICENSE_KEY}
# No 哥登堡 service. No health checks. No resource limits.基礎設施差異很大:Gotenberg 需要容器部署、健康監控、資源分配和服務依賴關係。 IronPDF與應用程式一起在進程內運行。
性能特徵
| 手術 | 哥登堡(暖容器) | 哥登堡(冷啟動) | IronPDF (初稿) | IronPDF (後續) |
|---|---|---|---|---|
| 簡單的 HTML | 150-300毫秒 | 2-5秒 | 1-2秒 | 50-150毫秒 |
| 複雜的 HTML | 500-1500毫秒 | 3-7秒 | 1.5-3秒 | 200-800毫秒 |
| URL渲染 | 1-5秒 | 3-10秒 | 1-5秒 | 500毫秒-3秒 |
| PDF合併 | 200-500毫秒 | 2-5秒 | 100-300毫秒 | 100-300毫秒 |
哥登堡的網路往返會使每個請求增加 10-100 毫秒以上的延遲。容器冷啟動會增加 2-5 秒的延遲。 IronPDF 的首次渲染會產生 Chromium 初始化(1-2 秒),但後續渲染開銷極小。
當團隊考慮從 哥登堡 遷移到IronPDF時
開發團隊基於以下幾個原因評估從 哥登堡 過渡到IronPDF :
基礎架構開銷: 哥登堡 需要 Docker、容器編排(Kubernetes/Docker Compose)、服務發現和負載平衡。 對於尋求更簡單部署方式的團隊來說,IronPDF 僅使用 NuGet 的方法消除了這些基礎架構的擔憂。
網路延遲: 哥登堡 的每次 PDF 操作都需要向單獨的服務發起 HTTP 請求,每次請求會增加 10-100 毫秒甚至更多的延遲。對於高流量應用來說,這種開銷會不斷累積。 IronPDF 的進程內方法在初始化後幾乎沒有開銷。
冷啟動問題:容器啟動可能會使首次請求延遲 2-5 秒。 即使是溫熱的容器也存在網路開銷。 每次 Pod 重新啟動、擴充或部署都會觸發冷啟動。 IronPDF 的冷啟動在每個應用程式生命週期中只會發生一次。
維運複雜性: 哥登堡 需要將容器健康狀況、擴展、日誌記錄和監控作為單獨的問題進行管理。 網路超時、服務不可用和容器崩潰都將成為應用程式需要關注的問題。 IronPDF使用標準的.NET異常處理。
Multipart 表單資料 API:每個 哥登堡 請求都需要建立一個帶有基於字串的參數的 multipart/form-data 有效負載-冗長且沒有編譯時類型檢查。 IronPDF提供具有 IntelliSense 支援的類型化 C# 屬性。
版本管理: 哥登堡 圖片的更新與您的應用程式是分開進行的。 API變更可能會導致整合失敗。 IronPDF版本透過NuGet管理,採用標準的.NET相依性管理。
優勢與考量
哥登堡優勢
-多語言架構:可與任何能夠啟動 HTTP 請求的語言配合使用 -語言無關:不限於.NET生態系統
- MIT許可證:自由開源軟體 微服務模式:適用於容器化架構
哥登堡考量
-基礎架構開銷:需要 Docker、Kubernetes 和負載平衡器。 -網路延遲:每次請求 10-100 毫秒以上 -冷啟動:容器初始化時間為 2-5 秒 -基於字串的 API:沒有類型安全或智慧感知功能 -分散式調試:需要分散式追蹤 -健康監測:其他需要管理的端點
IronPDF 的優勢
-零基礎架構:僅NuGet套件 -進程內效能:初始化後無網路延遲 -類型安全的 API:支援強型別屬性與智慧感知 -標準調試:普通的.NET調試器正常工作 -豐富的資源:大量的教學和文檔 專業支援:商業許可包含支援服務
IronPDF注意事項
- .NET專用:專為.NET生態系設計 -商業許可:生產用途必需
Gotenberg 和IronPDF代表了.NET應用程式中產生 PDF 的兩種截然不同的方法。 哥登堡 基於 Docker 的微服務架構引入了容器管理、網路延遲和維運複雜性。 每次 PDF 操作都需要 HTTP 通信,並伴隨相應的故障模式和冷啟動懲罰。
IronPDF以進程內庫的形式提供與 Chromium 相同的渲染功能。 NuGet套件消除了 Docker 容器、網路呼叫和基礎架構管理。 類型化的 C# API 取代了基於字串的多部分錶單資料。 標準.NET異常處理取代了 HTTP 狀態碼和網路故障模式。
隨著各組織規劃.NET 10、C# 14 以及到 2026 年的應用程式開發,微服務基礎架構開銷和進程內程式庫的簡單性之間的選擇會對部署和營運複雜性產生重大影響。 對於希望在保持 HTML/CSS/ JavaScript渲染保真度的同時減輕基礎設施負擔的團隊來說, IronPDF可以有效地滿足這些要求。
