跳至頁尾內容
遷移指南

如何用 C# 從 Gotenberg 轉移到 IronPDF

從Gotenberg遷移到IronPDF將您的.NET PDF工作流程從基於Docker的微服務架構和HTTP API呼叫轉變為內加工本C#程式庫。 本指南提供了一個全面的逐步遷移路徑,消除了專業.NET開發者的基礎設施開銷、網路延遲和容器管理的複雜性。

為什麼從Gotenberg遷移到IronPDF

Gotenberg架構問題

Gotenberg是一個用於PDF生成的基於Docker的微服務架構。 雖然功能強大且靈活,但對C#應用程式引入了顯著的複雜性:

  1. 基礎設施開銷:需要Docker、容器編排(Kubernetes/Docker Compose)、服務發現和負載均衡。 每次部署都變得更加複雜。

  2. 網路延遲:每次PDF操作都需要HTTP呼叫到一個獨立的服務——每個請求額外增加10-100毫秒的延遲。在高並發場景中,這種延遲很快就會積累。

  3. 冷啟動問題:容器啟動可能會在首次請求中增加2-5秒。 每次pods重啟、每次擴展事件和每次部署都會觸發冷啟動。

  4. 操作複雜性:您必須管理容器健康狀況、擴展、日誌記錄和監控,這些與您的主要應用程式是分開的問題。

  5. 多部分表單資料:每個請求需要構造多部分表單資料,有冗長,容易出錯,且維護繁瑣。

  6. 故障點:網路超時、服務不可用和容器崩潰都成為需要您處理的責任。

  7. 版本管理:Gotenberg映像獨立於您的應用程式進行更新; API變更可能會意外破壞整合。

Gotenberg與IronPDF比較

方面 Gotenberg IronPDF
部署 Docker容器 + 編排 單個NuGet套件
架構 微服務(REST API) 內加工本程式庫
每次請求延遲 10-100毫秒以上(網路往返) < 1毫秒開銷
冷啟動 2-5秒(容器初始化) 1-2秒(僅首次渲染)
基礎設施 Docker,Kubernetes,負載均衡器 不需要任何基礎設施
故障模式 網路、容器、服務故障 標準的.NET異常
API風格 REST多部分/表單資料 內建C#方法呼叫
擴展 水平(更多容器) 垂直(內處理)
除錯 需要分佈式跟踪 標準除錯器
版本控制 容器映像標籤 NuGet套件版本

對於以當前.NET版本為目標的團隊而言,IronPDF提供了一個沒有基礎設施依賴的基礎,並能夠自然而然地與現代.NET模式整合。


遷移複雜性評估

功能的預估努力程度

功能 遷移複雜性
HTML轉PDF 非常低
URL到PDF 非常低
自定紙張尺寸
邊距
PDF合併
頁眉/頁腳
等待延遲
PDF/A轉換

範式轉變

這次Gotenberg遷移的基礎轉變是從使用多部分表單資料的HTTP API呼叫內建C#方法呼叫:

Gotenberg:HTTP POST多部分表單數據到Docker容器
IronPDF:直接使用C#對象的方法呼叫

開始之前

前提條件

  1. .NET版本: IronPDF支援.NET Framework 4.6.2+和.NET Core 3.1+ / .NET 5/6/7/8/9+
  2. 授權金鑰:ironpdf.com取得您的IronPDF授權金鑰
  3. 計劃移除基礎設施:記錄Gotenberg容器以便在遷移後報廢

識別所有Gotenberg使用情況

# Find direct HTTP calls to Gotenberg
grep -r "gotenberg\|/forms/chromium\|/forms/libreoffice\|/forms/pdfengines" --include="*.cs" .

# Find GotenbergSharpApiClient usage
grep -r "GotenbergSharpClient\|Gotenberg.Sharp\|ChromiumRequest" --include="*.cs" .

# Find Docker/KubernetesGotenbergconfiguration
grep -r "gotenberg/gotenberg\|gotenberg:" --include="*.yml" --include="*.yaml" .
# Find direct HTTP calls to Gotenberg
grep -r "gotenberg\|/forms/chromium\|/forms/libreoffice\|/forms/pdfengines" --include="*.cs" .

# Find GotenbergSharpApiClient usage
grep -r "GotenbergSharpClient\|Gotenberg.Sharp\|ChromiumRequest" --include="*.cs" .

# Find Docker/KubernetesGotenbergconfiguration
grep -r "gotenberg/gotenberg\|gotenberg:" --include="*.yml" --include="*.yaml" .
SHELL

NuGet包變更

# RemoveGotenbergclient (if using)
dotnet remove package Gotenberg.Sharp.API.Client

# Install IronPDF
dotnet add package IronPdf
# RemoveGotenbergclient (if using)
dotnet remove package Gotenberg.Sharp.API.Client

# Install IronPDF
dotnet add package IronPdf
SHELL

快速開始遷移

步驟1:更新授權配置

之前(Gotenberg):

Gotenberg不需要授權,但需要Docker基礎設施和容器URL。

private readonly string _gotenbergUrl = "http://localhost:3000";
private readonly string _gotenbergUrl = "http://localhost:3000";
Private ReadOnly _gotenbergUrl As String = "http://localhost:3000"
$vbLabelText   $csharpLabel

之後(IronPDF):

// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

步驟2:更新名稱空間的引入

// Before (Gotenberg)
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;
// Before (Gotenberg)
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;
Imports System.Net.Http
Imports System.Threading.Tasks
Imports System.IO

Imports IronPdf
Imports IronPdf.Rendering
$vbLabelText   $csharpLabel

完整API參考

Gotenberg端點到IronPDF映射

Gotenberg路徑 IronPDF等價
POST /forms/chromium/convert/html ChromePdfRenderer.RenderHtmlAsPdf()
POST /forms/chromium/convert/url ChromePdfRenderer.RenderUrlAsPdf()
POST /forms/pdfengines/merge PdfDocument.Merge()
POST /forms/pdfengines/convert pdf.SaveAs()帶設置
GET /health

表單參數到RenderingOptions映射

Gotenberg參數 IronPDF 屬性 轉換說明
paperWidth(英寸) RenderingOptions.PaperSize 使用枚舉或自定尺寸
paperHeight(英寸) RenderingOptions.PaperSize 使用枚舉或自定尺寸
marginTop(英寸) RenderingOptions.MarginTop 乘以25.4換算為毫米
marginBottom(英寸) RenderingOptions.MarginBottom 乘以25.4換算為毫米
printBackground RenderingOptions.PrintHtmlBackgrounds 布林值
landscape RenderingOptions.PaperOrientation Landscape枚舉
"3s" RenderingOptions.WaitFor.RenderDelay(ms) 將字串轉換為毫秒

程式碼遷移範例

範例1:基本HTML到PDF

之前(Gotenberg):

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");
    }
}
Imports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports System.IO

Module GotenbergExample
    Async Function Main() As Task
        Dim gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html"

        Using client As New HttpClient()
            Using content As New MultipartFormDataContent()
                Dim html = "<html><body><h1>Hello from Gotenberg</h1></body></html>"
                content.Add(New StringContent(html), "files", "index.html")

                Dim response = Await client.PostAsync(gotenbergUrl, content)
                Dim pdfBytes = Await response.Content.ReadAsByteArrayAsync()

                Await File.WriteAllBytesAsync("output.pdf", pdfBytes)
                Console.WriteLine("PDF generated successfully")
            End Using
        End Using
    End Function
End Module
$vbLabelText   $csharpLabel

之後(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");
    }
}
Imports System
Imports IronPdf

Class IronPdfExample
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()

        Dim html = "<html><body><h1>Hello from IronPDF</h1></body></html>"
        Dim pdf = renderer.RenderHtmlAsPdf(html)

        pdf.SaveAs("output.pdf")
        Console.WriteLine("PDF generated successfully")
    End Sub
End Class
$vbLabelText   $csharpLabel

差異是很顯著的:Gotenberg需要構建一個MultipartFormDataContent,進行一個異步HTTP POST至運行的Docker容器,並處理字節陣列的響應。 IronPDF將此減少為僅需三行程式碼使用ChromePdfRenderer方法呼叫——無網路開銷,無容器依賴,無異步複雜性。 查看HTML到PDF文件以獲取其他渲染選項。

範例2:URL轉PDF轉換

之前(Gotenberg):

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");
    }
}
Imports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports System.IO

Module GotenbergUrlToPdf
    Async Function Main() As Task
        Dim gotenbergUrl As String = "http://localhost:3000/forms/chromium/convert/url"

        Using client As New HttpClient()
            Using content As New MultipartFormDataContent()
                content.Add(New StringContent("https://example.com"), "url")

                Dim response As HttpResponseMessage = Await client.PostAsync(gotenbergUrl, content)
                Dim pdfBytes As Byte() = Await response.Content.ReadAsByteArrayAsync()

                Await File.WriteAllBytesAsync("webpage.pdf", pdfBytes)
                Console.WriteLine("PDF from URL generated successfully")
            End Using
        End Using
    End Function
End Module
$vbLabelText   $csharpLabel

之後(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");
    }
}
Imports System
Imports IronPdf

Class IronPdfUrlToPdf
    Shared Sub Main()
        Dim renderer As New ChromePdfRenderer()

        Dim pdf = renderer.RenderUrlAsPdf("https://example.com")

        pdf.SaveAs("webpage.pdf")
        Console.WriteLine("PDF from URL generated successfully")
    End Sub
End Class
$vbLabelText   $csharpLabel

Gotenberg方法需要使用不同的端點(/forms/chromium/convert/url),使用URL作為表單字段構建多部分內容,並處理異步HTTP響應。 IronPDF的PdfDocument物件。 瞭解更多關於URL到PDF轉換

範例3:自定義紙張尺寸和邊距

之前(Gotenberg):

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");
    }
}
Imports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports System.IO

Class GotenbergCustomSize
    Shared Async Function Main() As Task
        Dim gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html"

        Using client As New HttpClient()
            Using content As New MultipartFormDataContent()
                Dim 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")

                Dim response = Await client.PostAsync(gotenbergUrl, content)
                Dim pdfBytes = Await response.Content.ReadAsByteArrayAsync()

                Await File.WriteAllBytesAsync("custom-size.pdf", pdfBytes)
                Console.WriteLine("Custom size PDF generated successfully")
            End Using
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

之後(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");
    }
}
Imports System
Imports IronPdf
Imports IronPdf.Rendering

Module IronPdfCustomSize

    Sub Main()
        Dim renderer As New ChromePdfRenderer()

        renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter
        renderer.RenderingOptions.MarginTop = 50
        renderer.RenderingOptions.MarginBottom = 50

        Dim html As String = "<html><body><h1>Custom Size PDF</h1></body></html>"
        Dim pdf = renderer.RenderHtmlAsPdf(html)

        pdf.SaveAs("custom-size.pdf")
        Console.WriteLine("Custom size PDF generated successfully")
    End Sub

End Module
$vbLabelText   $csharpLabel

Gotenberg需要基於字串的參數("0.5")新增到多部分表單資料中——無型別安全,無IntelliSense,容易輸入錯誤。 IronPDF提供具有PdfPaperSize枚舉和數字邊距值的強型別屬性。 請注意IronPDF的邊距單位為毫米(50毫米≈2英寸),而Gotenberg使用英寸。


關鍵遷移注意事項

單位轉換

這次Gotenberg遷移中最重要的轉換是邊距單位:

// Gotenberg: margins in inches
content.Add(new StringContent("0.5"), "marginTop");    // 0.5 inches
content.Add(new StringContent("1"), "marginBottom");   // 1 inch

// IronPDF: margins in millimeters
renderer.RenderingOptions.MarginTop = 12.7;    // 0.5 inches × 25.4 = 12.7mm
renderer.RenderingOptions.MarginBottom = 25.4; // 1 inch × 25.4 = 25.4mm
// Gotenberg: margins in inches
content.Add(new StringContent("0.5"), "marginTop");    // 0.5 inches
content.Add(new StringContent("1"), "marginBottom");   // 1 inch

// IronPDF: margins in millimeters
renderer.RenderingOptions.MarginTop = 12.7;    // 0.5 inches × 25.4 = 12.7mm
renderer.RenderingOptions.MarginBottom = 25.4; // 1 inch × 25.4 = 25.4mm
' Gotenberg: margins in inches
content.Add(New StringContent("0.5"), "marginTop")    ' 0.5 inches
content.Add(New StringContent("1"), "marginBottom")   ' 1 inch

' IronPDF: margins in millimeters
renderer.RenderingOptions.MarginTop = 12.7    ' 0.5 inches × 25.4 = 12.7mm
renderer.RenderingOptions.MarginBottom = 25.4 ' 1 inch × 25.4 = 25.4mm
$vbLabelText   $csharpLabel

轉換公式:millimeters = inches × 25.4

同步與異步

由於HTTP通信,Gotenberg需要異步操作:

// Gotenberg: Forced async due to network calls
var response = await client.PostAsync(gotenbergUrl, content);
var pdfBytes = await response.Content.ReadAsByteArrayAsync();

// IronPDF: Synchronous in-process execution
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");

// IronPDF: Async wrapper if needed
var pdf = await Task.Run(() => renderer.RenderHtmlAsPdf(html));
// Gotenberg: Forced async due to network calls
var response = await client.PostAsync(gotenbergUrl, content);
var pdfBytes = await response.Content.ReadAsByteArrayAsync();

// IronPDF: Synchronous in-process execution
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");

// IronPDF: Async wrapper if needed
var pdf = await Task.Run(() => renderer.RenderHtmlAsPdf(html));
Imports System.Net.Http

' Gotenberg: Forced async due to network calls
Dim response = Await client.PostAsync(gotenbergUrl, content)
Dim pdfBytes = Await response.Content.ReadAsByteArrayAsync()

' IronPDF: Synchronous in-process execution
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")

' IronPDF: Async wrapper if needed
Dim pdf = Await Task.Run(Function() renderer.RenderHtmlAsPdf(html))
$vbLabelText   $csharpLabel

錯誤處理

// Gotenberg: HTTP error handling
try
{
    var response = await client.PostAsync(gotenbergUrl, content);
    response.EnsureSuccessStatusCode();  // What if 500? 503? Timeout?
}
catch (HttpRequestException ex) { /* Network error */ }
catch (TaskCanceledException ex) { /* Timeout */ }

// IronPDF: Standard .NET exceptions
try
{
    var pdf = renderer.RenderHtmlAsPdf(html);
}
catch (Exception ex)
{
    Console.WriteLine($"PDF generation failed: {ex.Message}");
}
// Gotenberg: HTTP error handling
try
{
    var response = await client.PostAsync(gotenbergUrl, content);
    response.EnsureSuccessStatusCode();  // What if 500? 503? Timeout?
}
catch (HttpRequestException ex) { /* Network error */ }
catch (TaskCanceledException ex) { /* Timeout */ }

// IronPDF: Standard .NET exceptions
try
{
    var pdf = renderer.RenderHtmlAsPdf(html);
}
catch (Exception ex)
{
    Console.WriteLine($"PDF generation failed: {ex.Message}");
}
Imports System
Imports System.Net.Http
Imports System.Threading.Tasks

' Gotenberg: HTTP error handling
Try
    Dim response = Await client.PostAsync(gotenbergUrl, content)
    response.EnsureSuccessStatusCode()  ' What if 500? 503? Timeout?
Catch ex As HttpRequestException
    ' Network error
Catch ex As TaskCanceledException
    ' Timeout
End Try

' IronPDF: Standard .NET exceptions
Try
    Dim pdf = renderer.RenderHtmlAsPdf(html)
Catch ex As Exception
    Console.WriteLine($"PDF generation failed: {ex.Message}")
End Try
$vbLabelText   $csharpLabel

移除基礎設施

遷移後,從您的基礎設施中移除Gotenberg:

# REMOVE from docker-compose.yml:
# services:
#   gotenberg:
#     image: gotenberg/gotenberg:8
#     ports:
#       - "3000:3000"
#     deploy:
#       resources:
#         limits:
#           memory: 2G
# REMOVE from docker-compose.yml:
# services:
#   gotenberg:
#     image: gotenberg/gotenberg:8
#     ports:
#       - "3000:3000"
#     deploy:
#       resources:
#         limits:
#           memory: 2G
YAML

效能考量

延遲比較

操作 Gotenberg(熱) Gotenberg(冷啟動) 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秒

消除基礎設施成本

資源 Gotenberg IronPDF
需要的容器 1到N(擴展) 0
每個容器的記憶體 512MB到2GB
每個請求的網路開銷 10-100毫秒 0毫秒
健康檢查端點 必需的 不需要
負載均衡器 通常需要 不需要

故障排除

問題1:不需要HttpClient模式

問題:程式碼仍在使用MultipartFormDataContent

解決方案:完全替換為ChromePdfRenderer

// Remove all of this:
// using var client = new HttpClient();
// using var content = new MultipartFormDataContent();
// content.Add(new StringContent(html), "files", "index.html");
// var response = await client.PostAsync(url, content);

// Replace with:
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
// Remove all of this:
// using var client = new HttpClient();
// using var content = new MultipartFormDataContent();
// content.Add(new StringContent(html), "files", "index.html");
// var response = await client.PostAsync(url, content);

// Replace with:
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
$vbLabelText   $csharpLabel

問題2:邊距單位錯誤

問題:遷移後PDF的邊距不正確。

解決方案:將英寸轉換為毫米:

//Gotenbergused inches: "0.5"
//IronPDFuses millimeters: 0.5 × 25.4 = 12.7
renderer.RenderingOptions.MarginTop = 12.7;
//Gotenbergused inches: "0.5"
//IronPDFuses millimeters: 0.5 × 25.4 = 12.7
renderer.RenderingOptions.MarginTop = 12.7;
$vbLabelText   $csharpLabel

問題3:容器URL引用

問題:程式碼包含http://gotenberg:3000或類似的URL。

解決方案:移除所有容器URL引用——IronPDF在內部運行:

// Remove:
// private readonly string _gotenbergUrl = "http://gotenberg:3000";

//IronPDFneeds no URL - it's in-process
var renderer = new ChromePdfRenderer();
// Remove:
// private readonly string _gotenbergUrl = "http://gotenberg:3000";

//IronPDFneeds no URL - it's in-process
var renderer = new ChromePdfRenderer();
$vbLabelText   $csharpLabel

遷移檢查表

遷移前

  • 列出程式碼庫中所有Gotenberg HTTP呼叫
  • 記錄當前的Gotenberg配置(超時設置,邊距,紙張尺寸)
  • 識別所有Docker/Kubernetes的Gotenberg配置
  • 獲得IronPDF授權金鑰
  • 計劃基礎設施撤役

程式碼遷移

  • 安裝IronPDF的NuGet套件:dotnet add package IronPdf
  • 移除Gotenberg客戶端套件
  • 將所有HTTP呼叫替換為IronPDF的方法呼叫
  • 將邊距單位從英寸轉換為毫米
  • 更新錯誤處理(HTTP錯誤→.NET異常)
  • 在啟動時新增授權金鑰初始化

基礎設施遷移

  • 從Docker Compose / Kubernetes中移除Gotenberg
  • 更新CI/CD管道(移除Gotenberg映像拉取)
  • 移除Gotenberg的健康檢查
  • 從配置中移除Gotenberg URL

測試

  • 測試 HTML 到 PDF 的轉換
  • 測試 URL 到 PDF 的轉換
  • 驗證邊距和尺寸的準確性
  • 在負載下進行性能測試
  • 測試首次渲染的加熱時間

遷移後

  • 移除Gotenberg容器部署
  • 將Gotenberg配置文件存檔
  • 更新文件
  • 監控應用程式的記憶體使用
  • 確認沒有孤立的網路連接

請注意Gotenberg是其各自所有者的註冊商標。 本網站與Gotenberg無關,並未經其協同公司支援或贊助。所有產品名稱、標誌和品牌屬於各自的擁有人。 比較僅供參考,反映撰寫時公開可用的資訊。

Curtis Chau
技術作家

Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。

除了開發,Curtis對物聯網(IoT)有濃厚的興趣,探索創新的方法來整合硬體和軟體。在空閒時間,他喜歡玩遊戲和建立Discord機器人,結合他對技術的熱愛與創造力。

Iron 支援團隊

我們線上24小時,每週5天。
聊天
電子郵件
給我打電話