.NetCore 2.1以后的HttpClient最佳实践

640?wx_fmt=gif


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

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

01介绍

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

02什么是HttpClientFactory?

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

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

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

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

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

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

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

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

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

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

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

03如何使用HttpClientFactory

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

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

640services.AddHttpClient();640


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

640?wx_fmt=png

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

640在项目中安装Microsoft.Extension.Http包即可640


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

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

HttpClientFactory收集这些HttpClientHandler实例并管理它们的生命周期,以解决之前提到的一些问题。每次我们要求HttpClient时,我们都会得到一个新实例,它可能(或可能不)使用现有的HttpClientHandler。HttpClient本身并没有问题。

 一旦创建,由此创建的所有HttpClientHandler将被默认保持约2分钟。这意味着针对同一个CreateClient的任何新请求都可以共享处理程序,因此也可以共享连接。当HttpClient存在时,它的处理程序将保持可用状态,并且它将再次共享连接。


640两分钟后,每个HttpClientHandler都标记为已过期。过期状态只是标记它们,以便在创建任何新的HttpClient实例时不再使用它们。但是,它们不会立即销毁,因为其他HttpClient实例可能正在使用它们。HttpClientFactory使用后台服务监视过期的处理程序,一旦它们不再被引用,就可以正确释放它们,也允许它们的连接被关闭。640



04概要

640通过使用HttpClientfactory我们不需要考虑如何管理HttpClient的生命周期或担心遇到DNS问题。以上只是HttpClient小小的最佳使用推荐,还有其他高级用法,例如和Polly的结合使用。640


640?wx_fmt=gif

640?wx_fmt=gif


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

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

相关文章

D. Multiset(树状数组 + 二分)

Multiset 可能更好的阅读体验 思路 二分 树状数组做法 我们发现每个数的范围是$ < 1e6$的&#xff0c;所以可以直接在线操作&#xff0c;不用离散化离线操作。 这个时候我们的treetreetree数组就相当与一个桶&#xff0c;每个桶里统计的是值为其下标的个数&#xff0c…

Codeforces Round #381 (Div. 1) A. Alyona and mex 构造

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 你需要确定一个长度为nnn的数组aaa&#xff0c;满足给定的mmm个[l,r][l,r][l,r]限制&#xff0c;需要保证构造出来的aaa数组对于每个[l,r][l,r][l,r]的mexmexmex最小值最大。 n,m≤1e5n,m\le1e5n,m≤1e5 思…

点分治(简要讲解 + 模板)

树上点分治 思想 两个点之间的距离无非就是两种关系&#xff1a;我们约定dis[i]dis[i]dis[i]表示这个点到当前根节点的距离 dis[u]dis[v]dis[u] dis[v]dis[u]dis[v]&#xff0c;在同一个根节点的不同子树上。dis[u]dis[v]dis[u] dis[v]dis[u]dis[v]&#xff0c;在同一个棵子…

在 alpine 中使用 NPOI

在 alpine 中使用 NPOIIntro在 .net 中常使用 NPOI 来做 Excel 的导入导出&#xff0c;NPOI 从 2.4.0 版本开始支持 .netstandard2.0&#xff0c;在 dotnet core 应用也可以用 DotNetCore.NPOI。对于 .NET Core 应用来说&#xff0c;如果没有特殊的需求&#xff0c;alpine 是最…

Educational Codeforces Round 16 C. Magic Odd Square 矩阵构造

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个奇数nnn&#xff0c;让你构造一个n∗nn*nn∗n的矩阵&#xff0c;矩阵的每个位置依次填上[1,n∗n]之内的数[1,n*n]之内的数[1,n∗n]之内的数&#xff0c;满足每行、每列、以及主对角线的和都是奇数。…

关于WCF、WebAPI、WebService之间的区别总结 分布式通信技术

早在1996年Gartner就前瞻性地提出了面向服务架构的思想(SOA)&#xff0c;SOA 的走红在很大程度上归功于 Web Service 标准的成熟和应用的普及。Service Oriented Ambiguity 中文一般理解为&#xff1a;面向服务架构&#xff0c;简称SOA&#xff0c;这个概念算得上微服务的鼻祖了…

LCA求解的四种模板

LCA求解的四种模板 或许更好的阅读体验 树剖在线求解LCA 思想 树剖这里就不多解释了&#xff0c;求解LCA的过程就是轻重链的跳转&#xff0c;跟树剖求任意两点间的距离一样的操作&#xff0c;只不过不用线段树去维护disdisdis了&#xff0c;那就直接上代码吧。 代码 #inc…

HDU - 1998 奇数阶魔方

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个奇数nnn&#xff0c;构造一个nnn阶幻方。 3≤n≤193\le n\le 193≤n≤19 思路&#xff1a; 模板题了&#xff0c;直接构造一个幻方即可。 首先在第一行中间放一个111&#xff0c;之后每次看一下(…

Azure 物联网开发者体验 7 月更新:边缘计算开发工具,ARM64 设备开发,VS Code 容器化开发工具...

欢迎来到 Azure 物联网开发者体验的 7 月更新&#xff01;在本次发布中&#xff0c;微软为物联网开发人员提供了许多新的功能和改进&#xff01;物联网边缘计算开发工具正式发布Azure IoT Edge 于 2017 年发布。随着近两年的对边缘计算开发工具的不断开发与改善&#xff0c;Azu…

Tarjan缩点

Tarjan缩点 或许更好的阅读体验 P3387 【模板】缩点 思路 既然时缩点的模板&#xff0c;那么缩点自然少不了了&#xff0c;缩点后我们的到新的有向无环图&#xff0c;然后再利用这个无环图去找一条最大权值的路径&#xff0c;路径和即为答案。 我们改如何选取起点来避免不…

.NET中的值类型与引用类型

.NET中的值类型与引用类型这是一个常见面试题&#xff0c;值类型(Value Type)和引用类型(Reference Type)有什么区别&#xff1f;他们性能方面有什么区别&#xff1f;TL;DR&#xff08;先看结论&#xff09;值类型引用类型创建位置栈托管堆赋值时复制值复制引用动态内存分配无需…

Canada Cup 2016 C. Hidden Word 字符串构造

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个长度为272727的字符串sss&#xff0c;其中262626个字母每种都至少出现一次&#xff0c;让你构造一个213213213的矩阵&#xff0c;使得每个字母都出现一次&#xff0c;并且存在一条路径&#xff0c;经…

E:Johnny and Grandmaster

Johnny and Grandmaster 或许更好的阅读体验 思路 这道题就是把一组数分成两个集合&#xff0c;使这两个集合的对p的次方的和的差的最小值&#xff0c;也就是求sum1−sum2sum1 - sum2sum1−sum2得最小值&#xff0c; 由于结果过大我们可能需要对结果取模。那么这题得关键在于…

跨语言调用Hangfire定时作业服务

背景Hangfire允许您以非常简单但可靠的方式执行后台定时任务的工作。内置对任务的可视化操作。非常方便。但令人遗憾的是普遍都是业务代码和hagnfire服务本身聚合在一个程序中运行&#xff0c;极大的限制了hangfire的扩展和跨语言调用。所以萌生了开发一个支持restful api调用的…

Codeforces Round #453 (Div. 1) D. Weighting a Tree 构造 + dfs树

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一颗nnn个点的图&#xff0c;每个点都有一个点权cic_ici​&#xff0c;要求你给每个边赋一个权值kik_iki​&#xff0c;要求对于每个点与他相连的边的权值之和等于这个点的点权cic_ici​。 n≤1e5,n−1≤…

Codeforces Round #648 (Div. 2)(A, B, C, D)

Codeforces Round #648 (Div. 2) 或许更好的阅读体验 A:Matrix Game 思路 题意可以说是非常简单的&#xff0c;我们选定的格子的行列都不能存在1&#xff0c;可以发现我们可以放的格子一定是固定的&#xff0c;然后这题就变成了技术总共可以放多少个棋子了&#xff0c;所以…

可落地微服务on k8s的持续集成/部署方案

我们隔一流的软件生产工艺还有多远&#xff1f;在距离15000公里外&#xff0c;Amazon一年可以进行5000万次部署&#xff0c;在这一边某电商平台的研发部门里&#xff0c;让他们引以为傲的是他们正在进行“敏捷”开发模式&#xff0c;并对外号称他们是以每周为迭代来进行升级。时…

Codeforces Round #579 (Div. 3) F1. Complete the Projects (easy version) 排序 + 贪心

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 比较直观的想法就是对于bi≥0b_i\ge0bi​≥0的项目&#xff0c;我们将aia_iai​从小到大排序&#xff0c;让后依次加bib_ibi​&#xff0c;如果有取不到的&#xff0c;显然就无解。否则再看…

历久弥新 - 微软万亿市值背后的文化支撑(下)|DevOps案例研究

内容来源&#xff1a;DevOps案例深度研究-Microsoft文化支撑研究战队&#xff08;本文只展示部分PPT研究成果&#xff0c;更多细节请关注案例分享会&#xff0c;及本公众号。&#xff09;本案例内容贡献者&#xff1a;陈飞&#xff08;Topic Leader&#xff09;、陈雨卿、郭子奇…

Codeforces Round #579 (Div. 3) F2. Complete the Projects (hard version) dp + 贪心

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 排序方式跟easyeasyeasy版本的一样&#xff0c;但是hardhardhard版本是输出最多能选多少&#xff0c;所以我们对b<0b<0b<0的情况不能直接贪心的来选了&#xff0c;考虑用dpdpdp来…