首页 > 网络编程 > ASP.NET > 正文

.NET Core 2.1中HttpClientFactory的最佳实践记录_实用技巧

2018-10-12 16:22:14

前言

ASP.NET Core 2.1中出现一个新的HttpClientFactory功能,

它有助于解决开发人员在使用HttpClient实例从其应用程序发出外部Web请求时可能遇到的一些常见问题。

介绍

在.NETCore平台的2.1新增了HttpClientFactory,虽然HttpClient这个类实现了disposable,但使用它的时候用声明using包装块的方式通常不是最好的选择。处理HttpClient,底层socket套接字不会立即释放。该HttpClient类是专为多个请求重复使用而创建的。需要不同的基地址,不同的HTTP标头和其他对请求个性化操作的场景时,需要手动管理多个HttpClient实例,为了简化HttpClient实例管理,.NET Core 2.1提供了一个新的HTTPClientFactory - 它可以创建,缓存和处理HttpClient实例。

什么是HttpClientFactory?

用ASP.NET团队的话说:“an opinionated factory for creating HttpClient instances”(一个用于创建HttpClient实例的最佳实践的工厂),并且是ASP.NET Core 2.1发布的新功能。根据大家以前使用HttpClient的经验,您可能遇到一些困扰的问题,有时甚至没有意识到您有问题(只是在并发并不大的场景没触发而已)。

第一个问题是当你在代码中创建太多的HttpClients时,这反过来会产生两个问题......

  • 这是低效的,因为每个请求都有自己的远程服务器连接池。这意味着您需要为每个创建的客户端支付重新连接到该远程服务器的成本。
  • 更大的问题是如果你创建了很多HttpClient并使用到他们,你可以遇到Socket耗尽,而你基本上已经太快地使用了过多的Socket。您可以同时打开多个Socket是有限制的。当您dispose销毁HttpClient时,它打开的连接在TIME_WAIT状态下保持打开状态最长240秒(如果来自远程服务器的任何数据包仍然通过)。

HttpClient实现了IDisposable,这通常会导致开发人员在使用IDisposable对象时遵循正常模式,在using块中创建它。这样可以确保一旦完成对象并且它已经超出范围,就可以正确销毁对象。

因此,最优的方法是重用HttpClient实例,以便也可以重用连接。HttpClient是一个可变对象,但只要你没有运行期改变它,它实际上是线程安全的并且可以共享。因此,一种常见的方法是将其注册为具有DI框架的单例模式,或者创建包含static静态实例的对象。

但是,这会产生新问题。以这种方式使用单个HttpClient将保持连接打开并且不遵守DNS生存时间(TTL)设置(总之就是同一个HttpClient实例只能有一个请求头,在被请求方发生更改时,由于是单例不能做个性化改变,否则导致其他请求失败)。现在连接将永远不会获得DNS更新,因此您正在与之通信的服务器将永远不会更新其地址。在某些情况下,这是完全有可能的,在以上这种情况下,您可以平衡许多主机,这些主机可能随着时间的推移而改变,或者可能使用Blue/Green 部署推出新服务。如果服务器消改变,则您的连接使用的IP可能不再响应您通过单个HttpClient发出的请求。

所以需要我们手动去管理每类服务器的HttpClient的实例来进行个性化请求头的构造和发起请求!

HttpClientFactory旨在帮助您开始解决这些问题,并提供了一种新的机制来创建在幕后为我们正确管理的HttpClient实例。它将为我们“做管理HttpClient的事”,我们可以专注于业务!虽然在参考HttpClient时提到了上述问题,但事实上问题的根源实际上发生在HttpClient上,HttpClient使用了HttpClientHandler。HttpClientFactory管理处理程序的生命周期,以便我们有一个可以重用的池,同时还可以(Rotating)轮换它们以使DNS不会过时。

使用HttpClient的昂贵部分实际上是创建HttpClientHandler和连接。以这种HttpClientFacotry方式汇集这些内容意味着我们可以更高效利用资源最节省地使用我们系统上的socket。当您使用HttpClientFactory请求HttpClient时,实际上每次都会获得一个新实例,这意味着我们不必担心会改变它的状态。此HttpClient可能(或可能不)使用池中的现有HttpClientHandler,从而使用现有打开的连接。

默认情况下,每个新创建的HttpClientHandler(派生自HttpMessageHandler)生命周期只有2分钟。通过services.AddHttpClient()创建HttpClientFactory实例时,可以根据每一个命名的Client客户机进行控制。达到生命周期后,处理程序将不会立即被释放掉,而是放入过期的池中。任何依赖于HttpClientFactory的处理程序链的客户端都可以继续使用它而没有任何问题。有一个后台作业检查过期的池,以查看处理程序的所有引用是否已在scope之外,此时可以将其释放掉。处理程序链过期后对新客户端的任何新请求都将获得新的处理程序链。

这种方法运行得相当不错,但.NET Core方面还有其他一些事情可能会进一步改善这种情况。.NET Core团队开发了一个新的ManagedHandler,它可以更正确地管理DNS,原则上可以保持更长时间,这意味着可以更有效地共享连接。这个新的处理程序还被设计为在不同的操作系统中更加一致地运行。在该工作完成之前,上面的处理程序池是一个合理的解决方法。

如何使用HttpClientFactory

我们将首先创建一个简单的WebAPI项目

接下来,我们需要转到我们的Startup.cs文件并注册一个服务。

services.AddHttpClient();services.AddScoped(typeof(ClassInService));//此处无关HttpClient,请暂时忽视他

在幕后,这将注册一些必需的服务,其中一个是IHttpClientFactory的实现。接下来,我们在业务中使用他

 public class ClassInService {  /// <summary>  /// 构建器  /// </summary>  /// <param name="clientFactory"></param>  public ClassInService(IHttpClientFactory clientFactory)  {   _clientFactory = clientFactory;  }}
private void HttpClientFactoryTest()  {   var client = _clientFactory.CreateClient("这是专门用来连接博客园的");//必须和services.AddHttpClient()中指定的名称对应   var content = new StringContent($"SID={SID}&safeKey={111}");   content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");   var response = client.PostAsync("MyBlogUrl", content);  }

这里我们首先添加对IHttpClientFactory的依赖,它将由DI系统注入ClassInService。IHttpClientFactory允许我们请求和接收HttpClient实例。

我们使用HttpClientFactory创建客户端。在幕后,HttpClientFactory将为我们创建一个新的HttpClient。但是等等,之前说过为每个请求使用新的HttpClient是很糟糕。但此处的创建的httpclient是在他所管理的池子中,并不每个请求都会是新的socket。

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-httpclientfactory-aspnetcore

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

  • 相关标签:ASP.NET
  • 本文发布HTML5中文学习网 ,转载请注明出处,感谢您!
  • 相关文章


  • 曝网友假装外国人写投诉信 ofo秒退押金并回函致歉
  • 苹果市值缩水逾2000亿美元 遭多家投行下调目标价
  • Asp.net Core与类库读取配置文件信息的方法_实用技巧
  • asp.net在Repeater嵌套的Repeater中使用复选框详解_实用技巧
  • 利用IIS调试ASP.NET网站程序的完整步骤_实用技巧
  • Asp.Net Core轻松学习系列之配置文件_实用技巧
  • ASP.NET 页生命周期概述(小结)_实用技巧
  • 详解ASP.NET Core WebApi 返回统一格式参数_实用技巧
  • 2018年网络流行语有哪些?2018年十大网络流行语盘点
  • 华为首席财务官孟晚舟被暂扣 深圳市政府要求加方立即放人!
  • 独孤九贱(4)_PHP视频教程

    江湖传言:PHP是世界上最好的编程语言。真的是这样吗?这个梗究竟是从哪来的?学会本课程,你就会明白了。 PHP中文网出品的PHP入门系统教学视频,完全从初学者的角度出发,绝不玩虚的,一切以实用、有用...

    独孤九贱(5)_ThinkPHP5视频教程

    ThinkPHP是国内最流行的中文PHP开发框架,也是您Web项目的最佳选择。《php.cn独孤九贱(5)-ThinkPHP5视频教程》课程以ThinkPHP5最新版本为例,从最基本的框架常识开始,将...

    独孤九贱(1)_HTML5视频教程

    《php.cn原创html5视频教程》课程特色:php中文网原创幽默段子系列课程,以恶搞,段子为主题风格的php视频教程!轻松的教学风格,简短的教学模式,让同学们在不知不觉中,学会了HTML知识。 ...

    ThinkPHP5实战之[教学管理系统]

    本套教程,以一个真实的学校教学管理系统为案例,手把手教会您如何在一张白纸上,从零开始,一步一步的用ThinkPHP5框架快速开发出一个商业项目。

    PHP入门视频教程之一周学会PHP

    所有计算机语言的学习都要从基础开始,《PHP入门视频教程之一周学会PHP》不仅是PHP的基础部分更主要的是PHP语言的核心技术,是学习PHP必须掌握的内容,任何PHP项目的实现都离不开这部分的内容,通...

    作者信息

    kevin

    永远在学习的路上!

    相关教程

  • javascript初级视频教程 javascript初级视频教程
  • jquery 基础视频教程 jquery 基础视频教程
  • javascript三级联动视频教程 javascript三级联动视频教程
  • 独孤九贱(3)_JavaScript视频教程 独孤九贱(3)_JavaScript视频教程
  • 独孤九贱(6)_jQuery视频教程 独孤九贱(6)_jQuery视频教程
  • 热门教程