Azure NotificationHubClient 在 Azure 函数上密集使用时抛出 SocketException [英] Azure NotificationHubClient throws SocketException when used on Azure function intensively
问题描述
我们使用 Azure 函数通过 Azure NotificationHubClient 发送推送通知.这个函数在实时环境的高峰时间被调用很多次,结果我们得到了很多从 NotificationHubClient.SendNotificationAsync() 方法抛出的 SocketExceptions.
We are using an Azure function to send push notifications via Azure NotificationHubClient. This function is called a lot at peak times on live environment and as a result we got a lot of SocketExceptions thrown from the NotificationHubClient.SendNotificationAsync() method.
异常详情:
Microsoft.Azure.NotificationHubs.Messaging.MessagingException: Unexpected exception encountered TimeStamp:2020-03-27T04:14:35.4655705Z ---> System.Net.Http.HttpRequestException: Cannot assign requested address ---> System.Net.Sockets.SocketException: Cannot assign requested address
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at Microsoft.Azure.NotificationHubs.NotificationHubClient.SendRequestAsync(HttpRequestMessage request, String trackingId, HttpStatusCode[] successfulResponseStatuses, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at Microsoft.Azure.NotificationHubs.ExceptionsUtility.HandleUnexpectedException(Exception ex, String trackingId)
at Microsoft.Azure.NotificationHubs.ExceptionsUtility.TranslateToMessagingException(Exception ex, Int32 timeoutInMilliseconds, String trackingId)
at Microsoft.Azure.NotificationHubs.NotificationHubClient.SendRequestAsync(HttpRequestMessage request, String trackingId, HttpStatusCode[] successfulResponseStatuses, CancellationToken cancellationToken)
at Microsoft.Azure.NotificationHubs.NotificationHubClient.SendNotificationImplAsync(Notification notification, String tagExpression, String deviceHandle, CancellationToken cancellationToken)
我们像这样创建 NotificationHubClient:
We create the NotificationHubClient like:
new NotificationHubClient(connectionString, hubName, new NotificationHubClientSettings{OperationTimeout = TimeSpan.FromSeconds(10)});
我观察到背后的 Microsoft 实现是在每个新的 NotificationHubClient 实例化上实例化一个新的 HttpClient - 这可能是问题(众所周知的套接字耗尽),但我不知道如何解决这个问题.
I've observed that the Microsoft implementation behind is instantiating a new HttpClient on each new NotificationHubClient instantiation - which would probably be the problem(the well known socket exhaustion), but I have no ideea how this could be tackled.
有没有人遇到过同样的问题并设法以某种方式解决它?谢谢
Has anyone confronted with the same problem and managed to fix it some way? Thanks
推荐答案
最后我们通过注入解决了这个问题
In the end we managed to overcome the problem by injecting
IHttpMessageHandlerFactory _httpMessageHandlerFactory;
在我们的类中并将其传递给构造函数中的 notificationHubClient:
in our class and pass it to the notificationHubClient in the constructor:
return new NotificationHubClient(connectionString, hubName,
new NotificationHubClientSettings
{
OperationTimeout = TimeSpan.FromSeconds(10),
MessageHandler = _httpMessageHandlerFactory.CreateHandler()
});
这篇关于Azure NotificationHubClient 在 Azure 函数上密集使用时抛出 SocketException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!