Error de conexión gRPC en contenedores Azure de IronPDF
Cuando IronPDF se implementa dentro de contenedores Docker en Azure Container Instances o Azure App Service, la comunicación gRPC entre la aplicación y el motor IronPDF puede fallar. Esto ocurre más a menudo después de que un contenedor queda inactivo o se reinicia, o cuando el canal gRPC no se configura con lógica de reintento.
Grpc.Core.RpcException: Status(StatusCode="Unavailable", Detail="failed to connect to all addresses")
Status(StatusCode="Unknown", Detail="Stream removed")
Estos errores ocurren porque los entornos de contenedores de Azure pueden apagar o reciclar contenedores durante períodos de inactividad. Sin una política de reintento en el canal gRPC, una sola conexión caída hace que la llamada falle inmediatamente en lugar de reconectarse. El cierre del flujo HTTP/2 y las configuraciones del canal específicas de la plataforma también pueden producir estos errores.
Solución
1. Configurar política de reinicio de contenedores a Siempre
En Azure Container Instances, configure la política de reinicio a Always. En Azure App Service, use un plan dedicado (Básico B1 o superior) en lugar del plan de Consumo, que escala a cero y termina los contenedores. Para cargas de trabajo que requieren conexiones persistentes, los contenedores gestionados por Kubernetes son una opción más estable.
2. Configurar Lógica de Reintento gRPC
Elija el enfoque que coincida con su marco de trabajo objetivo.
Para .NET Framework: use Grpc.Core.Channel con una política de reintento 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)
)
For .NET Core / .NET 5+: use Grpc.Net.Client.GrpcChannel with 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. Usar RemoteServer para una configuración más sencilla
Si no necesita opciones de canal personalizadas, RemoteServer proporciona soporte de reintento incorporado y es el punto de partida recomendado para la mayoría de las implementaciones de contenedores de Azure. Use esto en lugar de .Docker() cuando el motor y los contenedores de la aplicación no estén en la misma red local. Para la referencia completa de configuración de conexión, ver la guía del motor 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. Evitar el apagado del motor entre solicitudes
Por defecto, IronPDF apaga su motor entre solicitudes. Configurar SkipShutdown a true mantiene el proceso del motor activo, lo que evita el costo de reconexión y reduce la posibilidad de errores de conexión en contenedores de larga duración.
IronPdf.Installation.SkipShutdown = true;
IronPdf.Installation.SkipShutdown = true;
IronPdf.Installation.SkipShutdown = True
Consejos para depuración
Para obtener una salida de diagnóstico gRPC detallada, configure las siguientes variables de entorno en su Dockerfile o configuración del contenedor:
ENV GRPC_TRACE=all
ENV GRPC_VERBOSITY=DEBUG
Verifique cef.log y IronSoftware.log para detalles adicionales sobre fallas de conexión. Para aprender cómo recuperar archivos de registro de Azure, vea Archivos de registro Azure.

