Błędy połączenia gRPC w kontenerach IronPDF na platformie Azure
Gdy IronPDF jest wdrażany wewnątrz kontenerów Docker na platformie Azure Container Instances lub Azure App Service, komunikacja gRPC między aplikacją a silnikiem IronPDF może się nie powieść. Najczęściej dzieje się to po bezczynności lub ponownym uruchomieniu kontenera lub gdy kanał gRPC nie jest skonfigurowany z logiką ponawiania.
Grpc.Core.RpcException: Status(StatusCode="Unavailable", Detail="failed to connect to all addresses")
Status(StatusCode="Unknown", Detail="Stream removed")
Te błędy występują, ponieważ środowiska kontenerowe Azure mogą wyłączać lub recyklingować kontenery w okresach bezczynności. Bez polityki ponawiania na kanale gRPC, jedno zerwane połączenie powoduje natychmiastową awarię wywołania zamiast ponownego połączenia. Zamknięcie strumienia HTTP/2 i niedopasowania konfiguracji kanału specyficznego dla platformy mogą również generować te błędy.
Rozwiązanie
1. Ustaw politykę ponownego uruchamiania kontenera na Always
Na platformie Azure Container Instances ustaw politykę ponownego uruchamiania na Always. Na platformie Azure App Service używaj dedykowanego planu (Basic B1 lub wyższego) zamiast planu Consumption, który skaluje się do zera i kończy działanie kontenerów. Dla obciążeń wymagających stałych połączeń, kontenery zarządzane przez Kubernetes są bardziej stabilną opcją.
2. Skonfiguruj logikę powtórzeń gRPC
Wybierz podejście pasujące do twojego docelowego środowiska.
Dla .NET Framework: użyj Grpc.Core.Channel z polityką powtórzeń JSON
using Grpc.Core;
using IronPdf.GrpcLayer;
string jsonString = @"
{
""methodConfig"": [
{
""name"": [
{
""service"": ""ironpdfengineproto.IronPdfService""
}
],
""retryPolicy"": {
""maxAttempts"": 5,
""initialBackoff"": ""1.0s"",
""maxBackoff"": ""30s"",
""backoffMultiplier"": 1.5,
""retryableStatusCodes"": [
""UNAVAILABLE""
]
}
}
]
}";
var channel = new Channel("localhost:33350", ChannelCredentials.Insecure,
new[]
{
new ChannelOption("grpc.service_config", jsonString)
});
IronPdf.Installation.ConnectToIronPdfHost(
IronPdfConnectionConfiguration.WithCustomChannel(channel)
);
using Grpc.Core;
using IronPdf.GrpcLayer;
string jsonString = @"
{
""methodConfig"": [
{
""name"": [
{
""service"": ""ironpdfengineproto.IronPdfService""
}
],
""retryPolicy"": {
""maxAttempts"": 5,
""initialBackoff"": ""1.0s"",
""maxBackoff"": ""30s"",
""backoffMultiplier"": 1.5,
""retryableStatusCodes"": [
""UNAVAILABLE""
]
}
}
]
}";
var channel = new Channel("localhost:33350", ChannelCredentials.Insecure,
new[]
{
new ChannelOption("grpc.service_config", jsonString)
});
IronPdf.Installation.ConnectToIronPdfHost(
IronPdfConnectionConfiguration.WithCustomChannel(channel)
);
Imports Grpc.Core
Imports IronPdf.GrpcLayer
Dim jsonString As String = "
{
""methodConfig"": [
{
""name"": [
{
""service"": ""ironpdfengineproto.IronPdfService""
}
],
""retryPolicy"": {
""maxAttempts"": 5,
""initialBackoff"": ""1.0s"",
""maxBackoff"": ""30s"",
""backoffMultiplier"": 1.5,
""retryableStatusCodes"": [
""UNAVAILABLE""
]
}
}
]
}"
Dim channel = New Channel("localhost:33350", ChannelCredentials.Insecure,
{
New ChannelOption("grpc.service_config", jsonString)
})
IronPdf.Installation.ConnectToIronPdfHost(
IronPdfConnectionConfiguration.WithCustomChannel(channel)
)
Dla .NET Core / .NET 5+: użyj Grpc.Net.Client.GrpcChannel z RetryPolicy
using Grpc.Net.Client;
using Grpc.Net.Client.Configuration;
using IronPdf.GrpcLayer;
using Grpc.Core;
var retryPolicy = new RetryPolicy
{
MaxAttempts = 5,
InitialBackoff = TimeSpan.FromSeconds(1),
MaxBackoff = TimeSpan.FromSeconds(30),
BackoffMultiplier = 1.5,
RetryableStatusCodes = { StatusCode.Unavailable }
};
var methodConfig = new MethodConfig
{
Names = { MethodName.Default },
RetryPolicy = retryPolicy
};
var channel = GrpcChannel.ForAddress("http://localhost:33350", new GrpcChannelOptions
{
ServiceConfig = new ServiceConfig { MethodConfigs = { methodConfig } }
});
IronPdf.Installation.ConnectToIronPdfHost(
IronPdfConnectionConfiguration.WithCustomChannel(channel)
);
using Grpc.Net.Client;
using Grpc.Net.Client.Configuration;
using IronPdf.GrpcLayer;
using Grpc.Core;
var retryPolicy = new RetryPolicy
{
MaxAttempts = 5,
InitialBackoff = TimeSpan.FromSeconds(1),
MaxBackoff = TimeSpan.FromSeconds(30),
BackoffMultiplier = 1.5,
RetryableStatusCodes = { StatusCode.Unavailable }
};
var methodConfig = new MethodConfig
{
Names = { MethodName.Default },
RetryPolicy = retryPolicy
};
var channel = GrpcChannel.ForAddress("http://localhost:33350", new GrpcChannelOptions
{
ServiceConfig = new ServiceConfig { MethodConfigs = { methodConfig } }
});
IronPdf.Installation.ConnectToIronPdfHost(
IronPdfConnectionConfiguration.WithCustomChannel(channel)
);
Imports Grpc.Net.Client
Imports Grpc.Net.Client.Configuration
Imports IronPdf.GrpcLayer
Imports Grpc.Core
Dim retryPolicy As New RetryPolicy With {
.MaxAttempts = 5,
.InitialBackoff = TimeSpan.FromSeconds(1),
.MaxBackoff = TimeSpan.FromSeconds(30),
.BackoffMultiplier = 1.5,
.RetryableStatusCodes = {StatusCode.Unavailable}
}
Dim methodConfig As New MethodConfig With {
.Names = {MethodName.Default},
.RetryPolicy = retryPolicy
}
Dim channel As GrpcChannel = GrpcChannel.ForAddress("http://localhost:33350", New GrpcChannelOptions With {
.ServiceConfig = New ServiceConfig With {.MethodConfigs = {methodConfig}}
})
IronPdf.Installation.ConnectToIronPdfHost(
IronPdfConnectionConfiguration.WithCustomChannel(channel)
)
3. Użyj RemoteServer dla prostszej konfiguracji
Jeśli nie potrzebujesz niestandardowych opcji kanału, RemoteServer zapewnia wbudowane wsparcie dla ponawiania i jest zalecanym punktem wyjścia dla większości wdrożeń kontenerów na platformie Azure. Użyj tego zamiast .Docker(), gdy kontenery silnika i aplikacji nie znajdują się w tej samej lokalnej sieci. Dla pełnej dokumentacji konfiguracji połączenia zobacz przewodnik po silniku IronPDF.
IronPdf.Installation.ConnectToIronPdfHost(
IronPdfConnectionConfiguration.RemoteServer("http://your-container-host:33350")
);
IronPdf.Installation.ConnectToIronPdfHost(
IronPdfConnectionConfiguration.RemoteServer("http://your-container-host:33350")
);
Imports IronPdf
IronPdf.Installation.ConnectToIronPdfHost( _
IronPdfConnectionConfiguration.RemoteServer("http://your-container-host:33350") _
)
4. Zapobiegnij wyłączeniu silnika pomiędzy żądaniami
Domyślnie IronPDF wyłącza swój silnik pomiędzy żądaniami. Ustawienie SkipShutdown na true utrzymuje proces silnika aktywny, co unika opóźnień związanych z ponownym połączeniem i zmniejsza szansę na błędy połączenia w kontenerach działających przez długi czas.
IronPdf.Installation.SkipShutdown = true;
IronPdf.Installation.SkipShutdown = true;
IronPdf.Installation.SkipShutdown = True
Wskazówki dotyczące debugowania
Aby uzyskać szczegółowe dane diagnostyczne gRPC, ustaw następujące zmienne środowiskowe w swoim Dockerfile lub konfiguracji kontenera:
ENV GRPC_TRACE=all
ENV GRPC_VERBOSITY=DEBUG
Sprawdź cef.log i IronSoftware.log, aby uzyskać dodatkowe szczegóły dotyczące awarii połączenia. Aby dowiedzieć się, jak pobrać pliki dziennika z platformy Azure, zobacz Azure Log Files.

