azure - 我应该如何在 ASP.NET Core 2.0 API 中使用 HttpClient

标签 azure design-patterns dotnet-httpclient asp.net-core-2.0 servicepoint

我正在开发 ASP.NET Core 2.0 API,我的 API 需要调用另一个第三方 REST API 来上传和检索文件并获取文件列表和状态信息。我将在 Azure 中托管 API,并计划在我的暂存槽和生产槽之间进行蓝绿部署。

似乎最佳实践的普遍共识是通过 Startup.cs-->ConfigureServices 方法中的 DI 注册来设置 HTTPClient 的 Singleton 实例,以提高性能并避免在我新建时可能发生的套接字错误通过Using 语句在每次使用时释放HTTPClient 连接。以下链接对此进行了说明;

https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

https://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.110).aspx#Anchor_5

http://www.nimaara.com/2016/11/01/beware-of-the-net-httpclient/

但如果我这样做,那么我可能会面临一个问题,即当我在 Azure 中进行蓝绿部署时,单例实例将看不到任何 DNS 更改。以下链接对此进行了说明;

http://byterot.blogspot.co.uk/2016/07/singleton-httpclient-dns.html

https://github.com/dotnet/corefx/issues/11224

http://www.nimaara.com/2016/11/01/beware-of-the-net-httpclient/

现在的普遍共识是使用静态 HTTPClient 实例,但控制 ServicePoint 类的 ConnectionLeaseTimeout 值,将其设置为较短的值,该值将强制关闭连接以刷新 DNS。 This博客文章甚至讨论了 nuget 包中的一个很好的 RestClient 组件(Nima 的 Easy.Common),它可以正确解决 ConnectionLeaseTimeout 以及缓存的 DNS 值。

但是,ASP.NET Core 2.0 似乎并未完全实现 ServicePoint,因此 ASP.NET Core 2.0 目前并不真正支持这种方法。

任何人都可以建议我在 Azure 上运行的 ASP.NET Core 2.0 API 中使用 HttpClient 时应采取的正确方法吗?我希望能够进行蓝绿部署。那么,我是否应该求助于 using 语句并在每次使用时更新客户端,而只是遭受性能损失?

似乎必须有一个可靠且高性能的解决方案来满足这一常见需求。

最佳答案

您链接到的一些文章的问题在于,它们导致人们普遍认为设置 ConnectionLeaseTimeout 在套接字层中执行了某种黑魔法,并且如果你使用的平台不支持它,那你就完蛋了。这些文章没有触及该设置的实际用途,即定期向被调用的服务器发送一个 Connection: Close header ,从而造成了损害。就是这样。我已经从源头验证了这一点,并且很容易复制。事实上我已经在我的 Flurl 库中自己完成了,实现细节 herehere .

话虽如此,我个人认为 DNS 问题有点夸大其词。例如,请注意,连接闲置一段时间(默认为 100 秒)后会自动关闭。使用 HttpClient 作为单例的好处远远大于风险。

我的建议是为每个被调用的第三方服务使用一个实例。这里的想法是,您可以获得最大程度的重用,同时仍然利用像 DefaultRequestHeaders 这样的东西,这些东西往往特定于一项服务。如果您只调用一项服务,那么它只是一个单例。 (相反,如果您调用 1000 个不同的服务,则无论您如何分割,都无法避免 1000 个打开的套接字。)如果您不希望连接长时间处于空闲状态,并且希望对可能的 DNS 切换采取防御措施使用第 3 方服务,定期发送 Connection: close header ,或者简单地处置并重新创建 HttpClient。请注意,这是一种权衡,而不是完美的解决方案,应该有助于缓解问题。

关于azure - 我应该如何在 ASP.NET Core 2.0 API 中使用 HttpClient,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48066216/

相关文章:

c# - HttpWebRequest 对每个主机 2 个连接的限制是否适用于 HttpClient?

c# - 何时或是否在调用 ReadAsStreamAsync 时处理 HttpResponseMessage?

c# - 如何使用 System.Net.HttpListener 在 WebSocket 中启用 SSL

c# - Azure 中与 MongoDB 的离线数据同步

c# - main 之前的静态初始化

java - 带线程的观察者模式

.net - 启用/禁用 Azure 流量管理器端点

sql - 调用Azure逻辑应用程序中的存储过程期间的网关超时

java - 装饰一个继承 protected 可观察对象的类

.net - 使用 C# 的 Sharepoint 2013 REST API 调用