【发布时间】:2021-03-25 13:18:07
【问题描述】:
我们最近将基于 azure functions 持久功能的应用从专用的 s1/标准应用服务计划切换到动态 y1 计划以相同的金额,现在我们遇到了一个常见错误:
“连接尝试失败,因为连接方在一段时间后没有正确响应,或者建立连接失败,因为连接的主机没有响应。”
这会在应用运行大约一个小时后发生。异常来自 svcutil 生成的 wcf 客户端。我相当确定这与消费功能应用程序与“专用”应用程序计划的套接字连接限制有关,如https://docs.microsoft.com/en-us/azure/azure-functions/functions-scale#service-limits 所述,但并不完全相信,因为我没有看到日志消息“超出主机阈值:连接" 列于https://docs.microsoft.com/en-us/azure/azure-functions/manage-connections#connection-limit
我们的客户端实际上是围绕十几个 wcf 客户端的包装器,这些客户端在我们的包装器构造上实例化。包装器用 di 注册为单例
builder.Services.AddSingleton<IWrapperClient, OurSoapClient>();
public OurSoapClient(
IMemoryCache memoryCache,
IOptions<Options> options,
ILogger<OurSoapClient> log
)
{
this.options = options.Value;
this.memoryCache = memoryCache;
this.log = log;
this.metaClient = new Meta.MetaWebServiceClient(
Meta.MetaWebServiceClient.EndpointConfiguration.MetaWebServicePort,
this.options.MetaHref
);
this.wmsClient = new Wms.WmsWebServiceClient(
Wms.WmsWebServiceClient.EndpointConfiguration.WmsWebServicePort,
this.options.WmsHref
);
this.wmsStageItemsClient = new Wms.Stage.Items.WmsWebServiceClient(
Wms.Stage.Items.WmsWebServiceClient.EndpointConfiguration.WmsWebServicePort,
this.options.WmsHref
);
this.wmsReceiptClient = new Wms.Stage.ExpectedReceipts.WmsWebServiceClient(
Wms.Stage.ExpectedReceipts.WmsWebServiceClient.EndpointConfiguration.WmsWebServicePort,
this.options.WmsHref
);
this.wmsStageRmaClient = new Wms.Stage.Rma.WmsWebServiceClient(
Wms.Stage.Rma.WmsWebServiceClient.EndpointConfiguration.WmsWebServicePort,
this.options.WmsHref
);
this.wmsStageShipmentsClient = new Wms.Stage.Shipments.WmsWebServiceClient(
Wms.Stage.Shipments.WmsWebServiceClient.EndpointConfiguration.WmsWebServicePort,
this.options.WmsHref
);
this.wmsUpdateShipmentsClient = new Wms.Updates.ShippingResults.WmsWebServiceClient(
Wms.Updates.ShippingResults.WmsWebServiceClient.EndpointConfiguration.WmsWebServicePort,
this.options.WmsHref
);
this.wmsUpdatesReceivingResultsClient = new Wms.Updates.ReceivingResults.WmsWebServiceClient(
Wms.Updates.ReceivingResults.WmsWebServiceClient.EndpointConfiguration.WmsWebServicePort,
this.options.WmsHref
);
this.wmsUpdatesInventoryAdjustmentClient = new Wms.Updates.InventoryAdjustments.WmsWebServiceClient(
Wms.Updates.InventoryAdjustments.WmsWebServiceClient.EndpointConfiguration.WmsWebServicePort,
this.options.WmsHref
);
this.wmsInboundOrderClient = new Wms.Inbound.CurrentAndHistory.WmsWebServiceClient(
Wms.Inbound.CurrentAndHistory.WmsWebServiceClient.EndpointConfiguration.WmsWebServicePort,
this.options.WmsHref
);
this.wmsOutboundOrderClient = new Wms.Outbound.CurrentAndHistory.WmsWebServiceClient(
Wms.Outbound.CurrentAndHistory.WmsWebServiceClient.EndpointConfiguration.WmsWebServicePort,
this.options.WmsHref
);
this.wmsInboundOrderDetailsClient = new Wms.Inbound.CurrentAndHistoryDetails.WmsWebServiceClient(
Wms.Inbound.CurrentAndHistoryDetails.WmsWebServiceClient.EndpointConfiguration.WmsWebServicePort,
this.options.WmsHref
);
this.wmsOutboundOrderDetailsClient = new Wms.Outbound.CurrentAndHistoryDetails.WmsWebServiceClient(
Wms.Outbound.CurrentAndHistoryDetails.WmsWebServiceClient.EndpointConfiguration.WmsWebServicePort,
this.options.WmsHref
);
}
切换回标准应用服务计划似乎可以消除这种情况。 我相当肯定持久函数不是这里的原因,但只是为了清楚所有对客户端的调用都是从 Orchestrator 或 Activity 函数发生的......我们在两种函数类型中看到相同的失败错误。
我注意到重复的一个轶事是错误似乎发生在第二个 OurWrapperClient 实例化之后(它再次实例化所有 wcf 客户端)......因为它是一个单例,所以它必须是 azure 函数控制平面旋转另一个我的应用实例
有几个问题:
- 知道如何证明这是与最大出站连接数相关的问题吗?
- 关于这成为问题的原因的任何建议
- 假设这与 WCF 有关
- 使用 wcf 客户端的正确方法是什么,是否应该使用 usings 为每个调用实例化它们,还是可以像我们一样在每个包装器客户端实例化一次,然后只释放一次?
- 我们是否应该使用 DI 将它们实例化为单例,然后注入它们?这意味着我相信 DI 会调用 Dispose
- 有什么方法可以将要使用的http 客户端传递给wcf 客户端生成的代码?许多 azure 函数最佳实践都说为所有 http I/O 注入一个 http 客户端,但我不知道如何使用 WCF 做到这一点。
【问题讨论】:
-
这个问题的错误和你的一样,你可以看看:stackoverflow.com/questions/17693353/…
-
@TheobaldDu thx 但我的差异导致它不是立即的,只有在一段时间(〜小时)后它才会开始发生
-
MS 支持工单得出的结论是,分配给我的网络空间与我的目标存在通信问题,切换到不同的网络空间似乎可以解决问题
标签: wcf .net-core azure-functions wcf-client azure-durable-functions