Erros de Conexão gRPC em Contêineres Azure do IronPDF

This article was translated from English: Does it need improvement?
Translated
View the article in English

Quando o IronPDF é implementado dentro de contêineres Docker em Instâncias de Contêiner do Azure ou no Azure App Service, a comunicação gRPC entre o aplicativo e o motor IronPDF pode falhar. Isso acontece com mais frequência após um contêiner ficar ocioso ou reiniciado, ou quando o canal gRPC não está configurado com lógica de repetição.

Grpc.Core.RpcException: Status(StatusCode="Unavailable", Detail="failed to connect to all addresses")
Status(StatusCode="Unknown", Detail="Stream removed")

Esses erros ocorrem porque os ambientes de contêiner do Azure podem desligar ou reciclar contêineres durante períodos de inatividade. Sem uma política de repetição no canal gRPC, uma única conexão interrompida faz com que a chamada falhe imediatamente em vez de se reconectar. Fechamento de stream HTTP/2 e incompatibilidades de configuração do canal específicas da plataforma também podem produzir esses erros.

Solução

1. Defina a Política de Reinício do Contêiner para Sempre

Nas Instâncias de Contêiner do Azure, defina a política de reinício para Always. No Azure App Service, use um plano dedicado (Basic B1 ou superior) em vez do plano de Consumo, que escala para zero e termina os contêineres. Para cargas de trabalho que exigem conexões persistentes, contêineres gerenciados pelo Kubernetes são uma opção mais estável.

2. Configure a Lógica de Repetição gRPC

Escolha a abordagem que corresponde ao seu framework de destino.

Para .NET Framework: use Grpc.Core.Channel com uma política de repetição 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)
)
$vbLabelText   $csharpLabel

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)
)
$vbLabelText   $csharpLabel

3. Use RemoteServer para uma Configuração Mais Simples

Se você não precisar de opções de canal personalizadas, RemoteServer oferece suporte interno a repetição e é o ponto de partida recomendado para a maioria das implementações de contêineres Azure. Use isto em vez de .Docker() quando os contêineres do motor e do aplicativo não estiverem na mesma rede local. Para a referência de configuração completa de conexão, consulte o guia do IronPDF Engine.

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") _
)
$vbLabelText   $csharpLabel

4. Evite o Desligamento do Motor Entre as Solicitações

Por padrão, o IronPDF desliga seu motor entre as solicitações. Definindo SkipShutdown para true mantém o processo do motor ativo, o que evita a sobrecarga de reconexão e reduz a chance de erros de conexão em contêineres de longa execução.

IronPdf.Installation.SkipShutdown = true;
IronPdf.Installation.SkipShutdown = true;
IronPdf.Installation.SkipShutdown = True
$vbLabelText   $csharpLabel

Dicas de Depuração

Para obter saída de diagnóstico gRPC detalhada, defina as seguintes variáveis de ambiente em seu Dockerfile ou configuração de contêiner:

ENV GRPC_TRACE=all
ENV GRPC_VERBOSITY=DEBUG

Verifique cef.log e IronSoftware.log para obter detalhes adicionais sobre falhas de conexão. Para aprender como recuperar arquivos de log do Azure, consulte Arquivos de Log do Azure.

Curtis Chau
Redator Técnico

Curtis Chau é bacharel em Ciência da Computação (Universidade Carleton) e se especializa em desenvolvimento front-end, com experiência em Node.js, TypeScript, JavaScript e React. Apaixonado por criar interfaces de usuário intuitivas e esteticamente agradáveis, Curtis gosta de trabalhar com frameworks modernos e criar manuais ...

Leia mais
Pronto para começar?
Nuget Downloads 20,088,359 | Versão: 2026.7 recém-lançado
Still Scrolling Icon

Ainda está rolando a tela?

Quer provas rápidas? PM > Install-Package IronPdf
executar um exemplo Veja seu HTML se transformar em um PDF.