我使用自定义类" ApiProvider"
从Azure Function ServiceBusTrigger调用我的APIpublic class ApiProvider
{
private readonly string _backendUrl;
private static HttpClient _client;
private readonly TraceWriter _log;
public ApiProvider(TraceWriter log)
{
_pamUrl = Environment.GetEnvironmentVariable("ApiUrl");
_log = log;
_client = CreateHttpClient();
}
}
我为ServiceBus队列中发送的每条消息调用它,所以让我们说有1500条消息,它将调用我支持的1500次。
有些调用是成功的,但有时我在Azure Functions Log中有错误而没有太多信息!但根据Application Insights:
System.Net.Sockets.SocketException
Exception while executing function: QueueDirectory An error occurred while sending the request. Unable to connect to the remote server Only one usage of each socket address (protocol/network address/port) is normally permitted
我认为让HttpClient静态就足够了,但它似乎并没有完全解决我想的问题,或者我错过了什么?
环境: Azure Functions Runtime:1.0.11702.0
编辑:我的方法CreateHttpClient()的一点概述:
private static HttpClient CreateHttpClient()
{
string thumbprint = Environment.GetEnvironmentVariable("WEBSITE_LOAD_CERTIFICATES");
if (thumbprint != null)
{
_log.LogInformation("Get the certificate of thumbprint : " + thumbprint);
using (X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser))
{
certStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certCollection =
certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
// Get the first cert with the thumbprint
var certificate = certCollection.OfType<X509Certificate2>().FirstOrDefault();
if (certificate != null)
{
_log.LogInformation("Certificate has been found.");
var handler = new WebRequestHandler();
handler.ClientCertificates.Add(certCollection[0]);
return new HttpClient(handler);
}
_log.LogInformation("Certificate has not been found.");
}
}
return new HttpClient();
}
答案 0 :(得分:1)
您应该只创建一次HttpClient
,而不是每次请求:
private static HttpClient _client = new HttpClient();
或者如果你需要保持初始化:
public class ApiProvider
{
private readonly string _backendUrl;
private static HttpClient _client;
private readonly TraceWriter _log;
static ApiProvider()
{
_client = CreateHttpClient();
}
public ApiProvider(TraceWriter log)
{
_pamUrl = Environment.GetEnvironmentVariable("ApiUrl");
_log = log;
}
}
更新:
根据你的编辑,我建议:
从_log
中删除CreateHttpClient
用法,如果您遇到证书加载问题,则只会抛出异常。这应该允许保持此方法静态,并且如果设置存在问题,也会快速且明显地失败。
如果您确实需要CreateHttpClient
中的记录器,请将其设置为非静态并使用原始代码,但只需拨打CreateHttpClient
一次:
public ApiProvider(TraceWriter log)
{
_pamUrl = Environment.GetEnvironmentVariable("ApiUrl");
_log = log;
if (_client == null) _client = CreateHttpClient();
}
某种竞争条件是可能的,但我不会发现这个问题。如果需要,可以添加锁定。