前言
在ASP.NET核心2.1中有一个新的HttpClientFactory函数,
它可以帮助解决开发人员在使用HttpClient实例从他们的应用程序发出外部Web请求时可能遇到的一些常见问题。
介绍
在的2.1中添加了HttpClientFactory。NETCore平台。虽然HttpClient类实现了一次性,但在使用它时,使用包装块声明通常不是最佳选择。处理HttpClient时,底层套接字套接字不会立即释放。这个HttpClient类是专门为要重用的多个请求创建的。当需要不同的基址、不同的HTTP头等场景对请求进行个性化操作时,需要手动管理多个HttpClient实例。为了简化HttpClient实例的管理。NET Core 2.1提供了一个新的HttpClient Factory,可以创建、缓存和处理HttpClient实例。
什么是HttpClientFactory?
用ASP.NET团队的话来说,“创建http客户端实例的监督工厂”(创建http客户端实例的最佳实践工厂)是由ASP.NET的core 2.1发布的新功能。根据大家之前使用HttpClient的经验,可能会遇到一些比较麻烦的问题,有时候甚至没有意识到自己有问题(只是在并发量不大的场景下不会触发)。
第一个问题是,当您在代码中创建太多的HttpClients时,这又会产生两个问题.
这是低效的,因为每个请求都有自己的远程服务器连接池。这意味着您必须为创建的每个客户端支付重新连接到远程服务器的费用。更大的问题是,如果你创建大量的HttpClient并使用它们,你可能会用完套接字,并且你基本上使用太多的套接字太快。您可以同时打开多少个套接字是有限制的。当您准备销毁HttpClient时,它打开的连接将在TIME_WAIT状态下保持打开状态长达240秒(如果来自远程服务器的任何数据包仍然通过)。HttpClient实现了IDisposable,这通常会导致开发人员在使用IDisposable对象时遵循正常模式,并使用block创建它。这确保了一旦对象完成并且超出范围,就可以正确销毁它。
因此,最好的方法是重用HttpClient实例,这样连接也可以被重用。HttpClient是一个可变对象,但只要在运行时不更改它,它实际上是线程安全的,可以共享。因此,一种常见的方法是将其注册为DI框架的单例模式,或者创建一个包含static静态实例的对象。
然而,这将产生新的问题。以这种方式使用单个HttpClient将保持连接打开,并且不符合DNS生存时间(TTL)设置(简而言之,同一个HttpClient实例只能有一个请求头。当被请求方发生变化时,不能进行个性化处理,因为它是单个实例,否则其他请求会失败)。现在该连接将永远不会获得DNS更新,因此您正在与之通信的服务器将永远不会更新其地址。在某些情况下,这是完全可能的。在上述情况下,您可以平衡许多主机,这些主机可能会随着时间的推移而变化,或者可能会使用蓝色/绿色部署来启动新服务。如果服务器发生变化,用于连接的IP可能不再通过单个HttpClient响应您的请求。
因此,我们需要手动管理每种类型服务器的HttpClient实例来构造个性化的请求头并发起请求!
HttpClientFactory旨在帮助您开始解决这些问题,并提供了一种新的机制来创建一个在幕后为我们正确管理的HTTP Client实例。它将为我们“管理HttpClient”,我们可以专注于我们的业务!虽然在提到HttpClient时提到了上述问题,但实际上,问题的根源实际上发生在使用HttpClient Handler的HttpClient上。HttpClientFactory管理处理器的生命周期,这样我们就有了一个可重用的池,同时我们可以旋转它们,这样DNS就不会过时。
使用HttpClient最昂贵的部分实际上是创建HttpClientHandler和连接。在这个HttpClientFacotry中收集这些内容意味着我们可以更有效地使用资源,并且最经济地使用我们系统上的套接字。当您使用HttpClientFactory请求HttpClient时,您实际上每次都会获得一个新的实例,这意味着我们不必担心改变它的状态。该HttpClient可以使用也可以不使用池中现有的HttpClientHandler,从而使用现有的开放连接。
默认情况下,每个新创建的HttpClientHandler(从HttpMessageHandler派生)的生命周期只有2分钟。通过服务创建HttpClientFactory实例时。AddHttpClient(),可以根据每个命名的Client客户端进行控制。处理器达到生命周期后,不会立即释放,而是放入过期池中。任何依赖于HttpClientFactory的处理程序链的客户端都可以继续使用它,而不会出现任何问题。有一个后台作业会检查过期的池,以查看处理程序的所有引用是否都在范围之外,此时可以释放它。在处理程序链过期后,对新客户端的任何新请求都将获得一个新的处理程序链。
这种方法很有效,但是。NET Core,这可能会进一步改善这种情况。那个。NET Core团队开发了一个新的ManagedHandler,可以更正确地管理DNS,原则上可以保持更长时间,这意味着连接可以更有效地共享。这个新的处理程序也被设计成在不同的操作系统中更一致地运行。在工作完成之前,上述处理程序池是一个合理的解决方案。
如何使用HttpClientFactory
我们将首先创建一个简单的WebAPI项目
接下来,我们需要转到我们的Startup.cs文件并注册一个服务。
服务。AddHttpClient();服务。AddScoped(type of(class in service));//HttpClient在这里无关紧要,请暂时忽略
在幕后,这将注册一些必要的服务,其中之一是IHttpClientFactory的实现。接下来,我们在业务中使用他
服务中的公共类{///summary////builder////summary////param name=' client factory '/param服务中的公共类(ihttpclientfactory client factory){ _ client factory=client factory;} } private void httplientfactory test(){ varclient=_ client factory . create client('这是专门用来连接到博客公园的');//它必须对应于服务中指定的名称。AddHttpClient():varcontent=new string content($ ' sid={ sid } safe key={ 111 } ');内容。headers . content type=new MediaTypeHeaderValue(' application/x-www-form-URL encoded ');var响应=客户端。postsync(' MyBlogUrl ',内容);}这里我们首先添加对IHttpClientFactory的依赖,由DI系统注入到ClassInService中。IHttpClientFactory允许我们请求和接收HttpClient实例。
我们使用HttpClientFactory来创建客户端。在幕后,HttpClientFactory将为我们创建一个新的HttpClient。但是等等,为每个请求使用一个新的HttpClient是不好的。但是,这里创建的httpclient在它管理的池中,并且不是每个请求都是新的套接字。
HttpClientFactory收集这些HttpClientHandler实例,并管理它们的生命周期,以解决前面提到的一些问题。每次我们请求HttpClient时,我们都会得到一个新的实例,这个实例可能使用也可能不使用现有的HttpClientHandler。HttpClient本身没有问题。
一旦创建,默认情况下,由此创建的所有HttpClientHandler都将保留大约2分钟。这意味着对同一个CreateClient的任何新请求都可以共享处理程序,从而共享连接。当HttpClient存在时,它的处理程序将保持可用,并将再次共享连接。
两分钟后,每个HttpClientHandler都被标记为过期。过期状态只是标记它们,以便在创建任何新的HttpClient实例时不再使用它们。但是,它们不会被立即销毁,因为它们可能正被其他HttpClient实例使用。HttpClientFactory使用后台服务来监控过期的处理程序,一旦不再引用它们,就可以正确释放它们,并关闭它们的连接。
摘要
有了HttpClientfactory,我们不需要考虑如何管理HttpClient的生命周期,也不用担心DNS问题。以上只是对HttpClient最佳使用的一个小建议,还有其他高级用途,比如与Polly的组合。
参考:https://www.stevejgordon.co.uk/introduction-to-http客户工厂-aspnetcore
摘要
以上就是本文的全部内容。希望本文的内容对大家的学习或工作有一定的参考价值。有问题可以留言交流。谢谢你的支持。