跳至页脚内容
迁移指南

如何用 C# 从 Gotenberg 迁移到 IronPDF

从高登堡迁移到IronPDF可将您的 .NET PDF 工作流程从基于 Docker 的微服务架构与 HTTP API 调用转换为进程内的本地 C# 库。 本指南为专业的 .NET 开发人员提供了一个全面的、循序渐进的迁移路径,消除了基础架构开销、网络延迟和容器管理的复杂性。

为什么要从高登堡迁移到 IronPDF.

哥登堡架构问题

Gotenberg 是一种基于 Docker 的 PDF 生成微服务架构。 虽然功能强大且灵活,但它为 C# 应用程序带来了很大的复杂性:

1.基础设施开销:需要 Docker、容器编排(Kubernetes/Docker Compose)、服务发现和负载均衡。 每次部署都会变得更加复杂。

2.网络延迟:每次 PDF 操作都需要向单独的服务发起 HTTP 请求,每次请求会增加 10-100 毫秒以上的延迟。在高流量场景下,这种延迟会迅速累积。

3.冷启动问题:容器启动可能会给首次请求增加 2-5 秒的时间。 每次 pod 重启、每次扩展事件和每次部署都会触发冷启动。

4.操作复杂性:您必须将容器健康状况、扩展、日志记录和监控作为与主应用程序分开的独立问题进行管理。

5.多部分表单数据:每个请求都需要构建 multipart/form-data 有效负载——冗长、容易出错且难以维护。

6.故障点:网络超时、服务不可用和容器崩溃等问题都需要您负责处理。

7.版本管理:高登堡图片的更新与您的应用程序是分开的; API 的更改可能会意外破坏集成。

高登堡与IronPDF对比

方面 高登堡 IronPDF
部署 Docker 容器 + 协调 单个 NuGet 软件包
结构 微服务(REST API) 在建库
每次请求的延迟 10-100ms+(网络往返) < 1ms 开销
冷启动 2-5 秒(容器启动) 1-2 秒(仅限首次呈现)
基础设施 Docker、Kubernetes、负载平衡器 无要求
失败模式 网络、容器、服务故障 .NET 标准例外情况
API 风格 REST 多art/表单数据 本地 C# 方法调用
缩放 横向(更多容器) 纵向(处理中)
调试 需要分布式跟踪 标准调试器
版本控制 容器图像标签 NuGet 软件包版本

对于计划在 2025 年和 2026 年之前采用 .NET 10 和 C# 14 的团队来说,IronPDF 提供了一个面向未来的基础,零基础设施依赖性,可与现代 .NET 模式原生集成。


迁移复杂性评估

按功能估算的工作量

特征 迁移复杂性
HTML 至 PDF 极低
URL 至 PDF 极低
定制纸张大小 low
边距 low
PDF 合并 low
页眉/页脚 语言
等待延迟 low
PDF/A 转换 low

范式转换

Gotenberg 迁移的根本转变在于从使用 multipart 表单数据的 HTTP API 调用转变原生 C# 方法调用:

高登堡:  向 Docker 容器发送 HTTP POST 多址/表单数据
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.规划基础设施移除:记录哥登堡容器在迁移后的退役事宜

识别所有高登堡用法

# 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/Kubernetes高登堡configuration
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/Kubernetes高登堡configuration
grep -r "gotenberg/gotenberg\|gotenberg:" --include="*.yml" --include="*.yaml" .
SHELL

NuGet 软件包变更

# Remove高登堡client (if using)
dotnet remove package Gotenberg.Sharp.API.Client

# Install IronPDF
dotnet add package IronPdf
# Remove高登堡client (if using)
dotnet remove package Gotenberg.Sharp.API.Client

# Install IronPDF
dotnet add package IronPdf
SHELL

快速启动迁移

步骤 1:更新许可配置

之前(高登堡):

Gotenberg 不需要许可证,但需要带有容器 URL 的 Docker 基础设施。

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

After (IronPDF):

// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
' Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-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 参考

戈登堡端点到IronPDF的映射

哥登堡路线 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 不适用

表单参数到渲染选项映射

高登贝格参数 IronPDF 属性 转换注意事项
paperWidth(英寸) RenderingOptions.PaperSize 使用枚举或自定义大小
paperHeight(英寸) RenderingOptions.PaperSize 使用枚举或自定义大小
marginTop(英寸) RenderingOptions.MarginTop 毫米数乘以 25.4
marginBottom(英寸) RenderingOptions.MarginBottom 毫米数乘以 25.4
printBackground RenderingOptions.PrintHtmlBackgrounds 布尔
landscape RenderingOptions.PaperOrientation Landscape枚举
waitDelay RenderingOptions.RenderDelay 转换为毫秒

代码迁移示例

示例 1:将基本 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");
    }
}
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

After (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 需要构造一个 HttpClient,构建 MultipartFormDataContent,向正在运行的 Docker 容器发出异步 HTTP POST 请求,并处理字节数组响应。IronPDF将其简化为三行代码,并调用 ChromePdfRenderer 方法——没有网络开销,没有容器依赖,没有异步复杂性。 有关其他渲染选项,请参阅 HTML to PDF 文档

示例 2:URL 到 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");
    }
}
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

After (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的 RenderUrlAsPdf() 方法直接接受 URL,并同步返回一个 PdfDocument 对象。 了解有关 URL 至 PDF 转换的更多信息。

示例 3:自定义纸张大小和页边距

之前(高登堡):

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

After (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 要求将基于字符串的参数("8.5""11""0.5")添加到 multipart 表单数据中——没有类型安全,没有 IntelliSense,容易输入错误。IronPDF提供具有枚举和数值边距值的强类型属性。 请注意,IronPDF 页边距以毫米为单位(50 毫米≈ 2 英寸),而高登堡使用英寸。


关键迁移说明

单位转换

此次高登堡迁移中最重要的转换是保证金单位:

// 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

性能考虑

延迟比较

手术 哥登堡(温暖) 高登堡(冷启动) IronPDF (初渲染) IronPDF (后续)
简单的 HTML 150-300 毫秒 2-5 秒 1-2 秒 50-150ms
复杂的 HTML 500-1500ms 3-7 秒 1.5-3 秒 200-800ms
URL 渲染 1-5 秒 3-10 秒 1-5 秒 500ms-3s

消除基础设施成本

资源 高登堡 IronPDF
所需容器 1-N(缩放) 0
每个容器的内存 512MB-2GB 不适用
每次请求的网络开销 10-100 毫秒 0ms
健康检查终点 要求 不需要
负载平衡器 经常需要 不需要

故障排除

问题 1:不需要 HttpClient 模式

问题:代码仍然使用 HttpClientMultipartFormDataContent

解决方案:完全替换为 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 文件的边距不正确。

解决方法:将英寸转换为毫米:

//高登堡used inches: "0.5"
//IronPDFuses millimeters: 0.5 × 25.4 = 12.7
renderer.RenderingOptions.MarginTop = 12.7;
//高登堡used 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

迁移清单

迁移前

  • 清点代码库中所有高登堡HTTP 调用
  • 记录当前高登堡配置(超时、页边距、纸张尺寸)
  • 识别所有 Docker/Kubernetes高登堡配置
  • 获取IronPDF许可证密钥
  • 规划基础设施退役

代码迁移

  • 安装 IronPdf NuGet 包:dotnet add package IronPdf
  • 移除高登堡客户端软件包
  • 将所有对高登堡的 HTTP 调用替换为IronPDF方法调用
  • 将边距单位从英寸转换为毫米
  • 更新错误处理(HTTP 错误 → .NET 异常)
  • 添加启动时许可证密钥初始化功能

基础架构迁移

  • 从 Docker Compose/Kubernetes 中移除 Gotenberg
  • 更新 CI/CD 流水线(移除高登堡镜像拉取)
  • 移除哥特堡健康检查
  • 从配置中移除高登堡URL

测试

  • 测试 HTML 到 PDF 的转换
  • 测试 URL 到 PDF 的转换
  • 核实边距和尺寸准确性
  • 负载下的性能测试
  • 测试首次渲染预热时间

后迁移

  • 移除高登堡容器部署
  • 归档高登堡配置文件
  • 更新文档
  • 监控应用程序内存使用情况
  • 检查是否存在孤立的网络连接

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。

钢铁支援团队

我们每周 5 天,每天 24 小时在线。
聊天
电子邮件
打电话给我