Jak przeprowadzić migrację z Gotenberg do IronPDF w języku C#
Przejście zGotenbergnaIronPDFprzekształca przepływ pracy z plikami PDF w środowisku .NET z architektury mikrousług opartej na Dockerze z wywołaniami API HTTP w natywną bibliotekę C# działającą w ramach procesu. Niniejszy przewodnik zawiera kompleksową, szczegółową ścieżkę migracji, która eliminuje obciążenia infrastruktury, opóźnienia sieciowe oraz złożoność zarządzania kontenerami dla profesjonalnych programistów .NET.
Dlaczego warto przejść zGotenbergna IronPDF
Problem architektury Gotenberg
Gotenberg to oparta na Dockerze architektura mikrousług do generowania plików PDF. Chociaż jest to rozwiązanie potężne i elastyczne, wprowadza ono znaczną złożoność do aplikacji C#:
-
Obciążenie infrastruktury: Wymaga Docker, orkiestracji kontenerów (Kubernetes/Docker Compose), wykrywania usług i równoważenia obciążenia. Każde wdrożenie staje się coraz bardziej złożone.
-
Opóźnienia sieciowe: Każda operacja na pliku PDF wymaga wywołania HTTP do oddzielnej usługi — co wydłuża czas odpowiedzi o 10–100 ms lub więcej na żądanie. Opóźnienia te szybko się kumulują w scenariuszach o dużej objętości.
-
Problemy z zimnym startem: Uruchomienie kontenera może wydłużyć czas realizacji pierwszych żądań o 2–5 sekund. Każde ponowne uruchomienie podu, każde skalowanie w górę i każde wdrożenie powoduje uruchomienie od zera.
-
Złożoność operacyjna: Musisz zarządzać stanem kontenerów, skalowaniem, logowaniem i monitorowaniem jako kwestiami odrębnymi od głównej aplikacji.
-
Dane formularza wieloczęściowego: Każde żądanie wymaga tworzenia ładunków typu multipart/form-data — są one rozbudowane, podatne na błędy i uciążliwe w utrzymaniu.
-
Punkty awarii: Przekroczenie limitów czasu sieci, niedostępność usług i awarie kontenerów stają się Twoją odpowiedzialnością.
- Zarządzanie wersjami: ObrazyGotenbergsą aktualizowane niezależnie od aplikacji; Zmiany w API mogą nieoczekiwanie zakłócić integrację.
PorównanieGotenbergvs IronPDF
| Aspekt | Gotenberg | IronPDF |
|---|---|---|
| Wdrożenie | Kontener Docker + orkiestracja | Pojedynczy pakiet NuGet |
| Architektura | Mikroserwis (REST API) | Biblioteka w procesie |
| Opóźnienie na żądanie | 10-100ms+ (cykl sieciowy) | < 1ms narzutu |
| Zimny start | 2-5 sekund (inicjacja kontenera) | 1-2 sekund (tylko pierwsze renderowanie) |
| Infrastruktura | Docker, Kubernetes, balansowanie obciazen | Nie wymagana |
| Tryby awarii | Awaria sieci, kontenera, uslugi | Standardowe wyjątki .NET Standard |
| Styl API | REST multipart/form-data | Oryginalne wywolania metody C# |
| Skalowanie | Poziome (więcej kontenerow) | Pionowe (w procesie) |
| Debugowanie | Konieczne jest śledzenie rozproszone | Standardowy debugger |
| Kontrola wersji | Tagi obrazów kontenerow | Wersje pakietow NuGet |
Dla zespołów planujących wdrożenie .NET 10 i C# 14 w latach 2025 i 2026,IronPDFzapewnia przyszłościową podstawę bez żadnych zależności infrastrukturalnych, która natywnie integruje się z nowoczesnymi wzorcami .NET.
Ocena złożoności migracji
Szacowany nakład pracy według funkcji
| Funkcja | Złożoność migracji |
|---|---|
| HTML do PDF | Bardzo niski |
| URL do pliku PDF | Bardzo niski |
| Niestandardowy rozmiar papieru | Low |
| Marginesy | Low |
| Łączenie plików PDF | Low |
| Nagłówki/stopki | Medium |
| Opóźnienia | Low |
| Konwersja do formatu PDF/A | Low |
Zmiana paradygmatu
Podstawową zmianą w tej migracjiGotenbergjest przejście z wywołań API HTTP z wieloczęściowymi danymi formularza na natywne wywołania metod C#:
Gotenberg: HTTP POST multipart/form-data do kontenera Docker
IronPDF: Bezpośrednie wywołania metod na obiektach C#
Zanim zaczniesz
Wymagania wstępne
- Wersja .NET:IronPDFobsługuje .NET Framework 4.6.2+ oraz .NET Core 3.1+ / .NET 5/6/7/8/9+
- Klucz licencyjny: Uzyskaj klucz licencyjnyIronPDFna stronie ironpdf.com
- Plan usunięcia infrastruktury: Dokumentacja kontenerówGotenbergw celu wycofania z eksploatacji po migracji
Zidentyfikuj wszystkie wystąpienia 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" .
Zmiany w pakiecie 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
Szybki start – migracja
Krok 1: Zaktualizuj konfigurację licencji
Przed (Gotenberg):
Gotenberg nie wymaga licencji, ale wymaga infrastruktury Docker z adresami URL kontenerów.
private readonly string _gotenbergUrl = "http://localhost:3000";
private readonly string _gotenbergUrl = "http://localhost:3000";
Private ReadOnly _gotenbergUrl As String = "http://localhost:3000"
Po (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"
Krok 2: Zaktualizuj importy przestrzeni nazw
// 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
Kompletna dokumentacija API
MapowanieGotenbergEndpoint do IronPDF
| Trasa Gotenberg | OdpowiednikIronPDF |
|---|---|
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() z ustawieniami |
GET /health |
Nie dotyczy |
Mapowanie parametru formularza do RenderingOptions
| Parametr Gotenberg | WłaściwościIronPDF | Uwagi do konwersji |
|---|---|---|
paperWidth (cale) |
RenderingOptions.PaperSize |
Użyj enum lub rozmiaru niestandardowego |
paperHeight (cale) |
RenderingOptions.PaperSize |
Użyj enum lub rozmiaru niestandardowego |
marginTop (cale) |
RenderingOptions.MarginTop |
Pomnoz przez 25,4 dla mm |
marginBottom (cale) |
RenderingOptions.MarginBottom |
Pomnoz przez 25,4 dla mm |
printBackground |
RenderingOptions.PrintHtmlBackgrounds |
Boolean |
landscape |
RenderingOptions.PaperOrientation |
Landscape enum |
waitDelay |
RenderingOptions.RenderDelay |
Konwertuj na milisekundy |
Przykłady migracji kodu
Przykład 1: Podstawowy HTML do PDF
Przed (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
Po (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
Różnica jest znaczna:Gotenbergwymaga skonstruowania HttpClient, zbudowania MultipartFormDataContent, wykonania asynchronicznego żądania HTTP POST do uruchomionego kontenera Docker oraz obsługi odpowiedzi w postaci tablicy bajtów.IronPDFredukuje to do trzech wierszy za pomocą wywołania metody ChromePdfRenderer — bez obciążenia sieci, bez zależności od kontenerów, bez złożoności asynchronicznej. Dodatkowe opcje renderowania można znaleźć w dokumentacji dotyczącej konwersji HTML do PDF.
Przykład 2: Konwersja adresów URL do formatu PDF
Przed (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
Po (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
PodejścieGotenbergwymaga innego punktu końcowego (/forms/chromium/convert/url), tworzenia treści wieloczęściowych z adresem URL jako polem formularza oraz obsługi asynchronicznych odpowiedzi HTTP. Metoda RenderUrlAsPdf() bibliotekiIronPDFprzyjmuje bezpośrednio adres URL i zwraca obiekt PdfDocument w trybie synchronicznym. Dowiedz się więcej o konwersji adresów URL do formatu PDF.
Przykład 3: Niestandardowy rozmiar papieru i marginesy
Przed (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
Po (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
Gotenberg wymaga parametrów opartych na ciągach znaków ("8.5", "11", "0.5") dodanych do danych formularzy wieloczęściowych — brak bezpieczeństwa typów, brak IntelliSense, łatwość popełnienia błędu podczas wpisywania.IronPDFzapewnia właściwości silnie typowane z wyliczeniami PdfPaperSize i numerycznymi wartościami marginesów. Należy pamiętać, że marginesy wIronPDFsą podawane w milimetrach (50 mm ≈ 2 cale), podczas gdyGotenbergużywa cali.
Ważne uwagi dotyczące migracji
Przeliczanie jednostek miar
Najważniejszą zmianą w tej migracjiGotenbergsą jednostki marginesów:
// 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
Formuła konwersji: millimeters = inches × 25.4
Synchroniczne a asynchroniczne
Gotenberg wymaga operacji asynchronicznych ze względu na komunikację HTTP:
// 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))
Obsługa błędów
// 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
Usunięcie infrastruktury
Po migracji usuńGotenbergze swojej infrastruktury:
# 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
Kwestie związane z wydajnością
Porównanie opóźnień
| Działanie | Gotenberg(Ciepły) | Gotenberg (Zimny start) | IronPDF(pierwsze renderowanie) | IronPDF(kontynuacja) |
|---|---|---|---|---|
| Prosty HTML | 150–300 ms | 2–5 sekund | 1–2 sekundy | 50–150 ms |
| Złożony kod HTML | 500–1500 ms | 3–7 sekund | 1,5–3 sekundy | 200–800 ms |
| Renderowanie adresów URL | 1–5 sekund | 3–10 sekund | 1–5 sekund | 500 ms–3 s |
Eliminacja kosztów infrastruktury
| Zasoby | Gotenberg | IronPDF |
|---|---|---|
| Wymagane kontenery | 1-N (skalowanie) | 0 |
| Pamięć na kontener | 512 MB–2 GB | Nie dotyczy |
| Obciążenie sieciowe na żądanie | 10–100 ms | 0 ms |
| Punkty końcowe kontroli stanu | Wymagane | Nie jest potrzebne |
| Moduł równoważenia obciążenia | Często potrzebne | Nie jest potrzebne |
Rozwiązywanie problemów
Problem 1: Wzory HttpClient nie są potrzebne
Problem: Kod nadal wykorzystuje HttpClient i MultipartFormDataContent.
Rozwiązanie: Zastąpić całość przez 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)
Problem 2: Błędne jednostki marginesów
Problem: Pliki PDF mają nieprawidłowe marginesy po migracji.
Rozwiązanie: Przeliczanie cali na milimetry:
//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;
Problem 3: Odwołania do adresów URL kontenerów
Problem: Kod zawiera http://gotenberg:3000 lub podobne adresy URL.
Rozwiązanie: Usuń wszystkie odniesienia do adresów URL kontenerów —IronPDFdziała w ramach procesu:
// 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();
Lista kontrolna migracji
Przed migracją
- Sporządź spis wszystkich wywołań HTTPGotenbergw kodzie źródłowym
- Udokumentuj aktualną konfigurację Gotenberga (limity czasu, marginesy, rozmiary papieru)
- Zidentyfikuj wszystkie konfiguracje Docker/Kubernetes Gotenberg
- Uzyskaj klucz licencyjny IronPDF
- Plan wycofania infrastruktury z eksploatacji
Migracja kodu
- Zainstaluj pakiet IronPdf NuGet:
dotnet add package IronPdf - Usuń pakiety klienta Gotenberg
- Zastąp wszystkie wywołania HTTP doGotenbergwywołaniami metod IronPDF
- Przelicz jednostki marginesu z cali na milimetry
- Zaktualizuj obsługę błędów (błędy HTTP → wyjątki .NET)
- Dodaj inicjalizację klucza licencyjnego podczas uruchamiania
Migracja infrastruktury
- UsuńGotenbergz Docker Compose / Kubernetes
- Zaktualizuj potoki CI/CD (usuń pobieranie obrazów z Gotenberga)
- Usuń testy sprawności Gotenberg
- Usuń adres URLGotenbergz konfiguracji
Testowanie
- Przetestuj konwersję HTML do PDF
- Przetestuj konwersję adresu URL do formatu PDF
- Sprawdź dokładność marginesów i rozmiarów
- Test wydajności pod obciążeniem
- Test czasu rozgrzewania pierwszego renderowania
Po migracji
- Usuń wdrożenia kontenerów Gotenberg
- Archiwum plików konfiguracyjnych Gotenberg
- Aktualizacja dokumentacji
- Monitorowanie wykorzystania pamięci przez aplikację
- Sprawdź, czy nie ma osieroconych połączeń sieciowych

