.NET Core 2.1中的HttpClientFactory最佳实践

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时,这反过来会产生两个问题......

  1. 这是低效的,因为每个请求都有自己的远程服务器连接池。这意味着您需要为每个创建的客户端支付重新连接到该远程服务器的成本。

  2. 更大的问题是如果你创建了很多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,请暂时忽视他

640?wx_fmt=png

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

640?wx_fmt=png

这里我们首先添加对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

相关文章: 

  • HttpClientFactory与Steeltoe结合来完成服务发现

  • 用HttpClientFactory来实现简单的熔断降级

  • .NET Core开发日志——HttpClientFactory

原文地址:https://www.cnblogs.com/xiaoliangge/p/9476568.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/320392.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

树学

文章目录题目描述题解1:代码:题解2:代码:传送时间限制:C/C 2秒,其他语言4秒 空间限制:C/C 262144K,其他语言524288K 64bit IO Format:> %lld 题目描述 牛妹有一张连通图,由n个点…

csp-2019 复赛游记

文章目录Day0Day\ 0Day 0Day1Day\ 1Day 1Day2Day\ 2Day 2总结:csp−J:csp-J:csp−J:csp−s:csp-s:csp−s:遥远的梦想:Day0Day\ 0Day 0 早上,在运动会上乱搞一波,然后在10点左右到了机房,然后发现巨佬几枚,远看似在认证…

Rainbond v3.7.0:实现企业级PaaS的稳定性

Rainbond v3.7.0:实现企业级PaaS的稳定性Rainbond在v3.7.0版本中释出了大量平台稳定性更新,并在应用管理功能、安全性和系统安装三方面进行了部分优化。作为IT基础系统平台,Rainbond从低耦合的架构设计、高可用的部署方式、自恢复与容错的设计…

简单多边形三角化(暴力)

简单多边形三角化(暴力) 说在前面 网上流传着各种神奇的多边形三角剖分算法,但是讲道理,实现难度太高了。。。也没有搜到其他人的实现。这里写个最暴力的做法。。随机数据验证没问题,欢迎 hack 实现 一个简单多边形的耳朵定义为:如…

牛客网【每日一题】4月13号 Accumulation Degree

文章目录题目描述样例分析:题意:题解:代码:本题目传送题目树学是这个题的简易版,也涉及换根问题,可以先看看这个 树学 时间限制:C/C 1秒,其他语言2秒 空间限制:C/C 32768…

微软把UWP定位成业务线应用程序开发平台

微软把UWP定位成传统业务线(LOB)应用程序开发平台,以使用Windows Template Studio实现快速应用程序开发为重点。但是,为了把LOB开发人员吸引到UWP平台,他们在做的事情不止这些。最初发布时,通用Windows平台…

读 《CSharp Coding Guidelines》有感

C# 编程指南前不久在 Github 上看见了一位大牛创建一个仓库:CSharpCodingGuidelines,打开之后看了一下 readme.md 相关描述,感觉应该很不错,于是就 clone 到本地拜读一下,这里列一些自己的笔记,方便日后回顾…

牛客网 【每日一题】4月10日 二分图染色(弱化版)

精讲 组合、容斥 文章目录题目:题意&&题解::代码:题目传送题目: 时间限制:C/C 1秒,其他语言2秒 空间限制:C/C 524288K,其他语言1048576K 64bit IO Format: %lld …

微软Windows Community Toolkit一览

为了满足业务线开发人员的需求,微软推出了Windows Community Toolkit。这个快速变化的库充当了新的UWP控件和功能的测试基础。在创建UWP之初,其重点目标是智能手机和平板电脑。这意味着大部分开发预算都花费在控件上,确保这些控件能够在有限的…

如何简单的在 ASP.NET Core 中集成 JWT 认证?

前情提要:ASP.NET Core 使用 JWT 搭建分布式无状态身份验证系统文章超长预警(1万字以上),不想看全部实现过程的同学可以直接跳转到末尾查看成果或者一键安装相关的 nuget 包自上一篇介绍如何在 ASP.NET Core 中集成 JWT 的博文发布…

【二分】【暴力】蛋糕(gmoj 3918)

蛋糕 gmoj 3918 题目大意: 有一个蛋糕,分成n∗mn*mn∗m个单位,现在横竖各切三刀,使其分成16个矩阵,使价值最小的矩阵价值最大 输出样例 5 5 95998 21945 23451 99798 74083输入样例 3数据范围 40%的数据&#x…

Music Problem

文章目录题目描述题意:题解:传送时间限制:C/C 2秒,其他语言4秒 空间限制:C/C 131072K,其他语言262144K 64bit IO Format: %lld 题目描述 Listening to the music is relax, but for obsessive(强迫症), it …

可扩展架构设计的三个维度

业界对于可扩展的系统架构设计有一个朴素的理念,就是:通过加机器就可以解决容量和可用性问题这一理念在“云计算”概念疯狂流行的今天,得到了广泛的认可!对于一个规模迅速增长的系统而言,容量和性能问题当然是首当其冲的。但是随着…

.NET Core开发日志——简述路由

有过ASP.NET或其它现代Web框架开发经历的开发者对路由这一名字应该不陌生。如果要用一句话解释什么是路由,可以这样形容:通过对URL的解析,指定相应的处理程序。回忆下在Web Forms应用程序中使用路由的方式:然后是MVC应用程序&…

博客开通

开通博客第一天,纪念一下——

.NetCore Cap 结合 RabbitMQ 实现消息订阅

开源分布式消息框架 Cap 可以在GitHub上拉也可以通过nuget添加上一篇博文写了 Windows RabbitMQ的安装使用 Cap支持事务,通过捕获数据库上下文连接对象实现 消息事务,消息持久化怎么来实现消息订阅 消费?使用起来非常简单,主要通过…

小H和游戏

文章目录题目描述题解:传送时间限制:C/C 2秒,其他语言4秒 空间限制:C/C 262144K,其他语言524288K 64bit IO Format:%lld 题目描述 小H正在玩一个战略类游戏,她可以操纵己方的飞机对敌国的N座城市(编号为1~N…

asp.net core 发布到 docker 容器时文件体积过大及服务端口的配置疑问

在 asp.net core 发布时,本人先后产生了3个疑问。1、发布的程序为什么不能在docker容器中运行当时在window开发环境中发布后,dotnet xxx.dll可以正常运行;但放入docker容器后就报 *.*.deps.json not found 的错误。后根据下面的文章解决了问题…

水题(water)(非详细解答)

传送 时间限制:C/C 1秒,其他语言2秒 空间限制:C/C 32768K,其他语言65536K 64bit IO Format: %lld 题目描述 其中,f(1)1;f(2)1;Z皇后的方案数:即在ZZ的棋盘上放置Z个皇后,使其互不攻击的方案数。…

网络流小结

最大流&#xff1a; EK算法&#xff1a; #include<iostream> #include<cstring> #include<cstdio> #include<queue> using namespace std; const int inf0x7fffffff; const int maxn10010; struct node{int u,v,f,next; }edge[300050]; int s,t,cnt,…