IronPDF Azure容器中的gRPC连接错误

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

当IronPDF部署在Azure容器实例或Azure App Service中的Docker容器内时,应用程序与IronPDF引擎之间的gRPC通信可能会失败。 这种情况通常在容器空闲或重启后,或者当gRPC通道未配置重试逻辑时发生。

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

这些错误发生的原因是Azure容器环境可能在空闲期间关闭或回收容器。 如果gRPC通道没有重试策略,单个连接丢失会导致调用立即失败,而不是重新连接。 HTTP/2流关闭和特定平台的通道设置不匹配也会导致这些错误。

解决方案

1. 设置容器重启策略为Always

在Azure容器实例上,将重启策略设置为Always。 在Azure App Service上,使用专用计划(Basic B1及以上)而不是缩放到零并终止容器的Consumption计划。 对于需要持久连接的工作负载,由Kubernetes管理的容器是一个更稳定的选择。

2. 配置gRPC重试逻辑

选择与您的目标框架匹配的方法。

对于.NET Framework:使用Grpc.Core.Channel结合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

对于.NET Core / .NET 5+:使用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. 使用RemoteServer进行更简单的配置

如果不需要自定义通道选项,RemoteServer提供了内置的重试支持,是大多数Azure容器部署的推荐起点。 当引擎和应用程序容器不在同一局域网时,使用这个替代.Docker()。 有关完整的连接配置参考,请参阅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") _
)
$vbLabelText   $csharpLabel

4. 防止请求之间引擎关闭

默认情况下,IronPDF会在请求之间关闭其引擎。 将true可以保持引擎进程存活,避免重新连接的开销,并减少长时间运行容器中连接错误的可能性。

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

调试提示

要获取详细的gRPC诊断输出,请在您的Dockerfile或容器配置中设置以下环境变量:

ENV GRPC_TRACE=all
ENV GRPC_VERBOSITY=DEBUG

检查IronSoftware.log以获取连接失败的更多详细信息。 要了解如何从Azure检索日志文件,请参阅Azure日志文件

Curtis Chau
技术作家

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

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

准备开始了吗?
Nuget 下载 20,088,359 | 版本: 2026.7 刚刚发布
Still Scrolling Icon

还在滚动吗?

想快速获得证据? PM > Install-Package IronPdf
运行示例看着你的HTML代码变成PDF文件。