ASP.Net Core2.1中的HttpClientFactory系列一

引言:

  ASP.NET Core2.1 中出现了一个新的 HttpClientFactory 功能, 它有助于解决开发人员在使用 HttpClient 实例从其应用程序中访问外部 web 资源时可能遇到的一些常见问题。关于HttpClientFactory 到底解决了那些HttpClient的严重问题,下面是我罗列出来的(原文来自于:https://www.infoq.com/news/2016/09/HttpClient)

  (1)在处理HttpClient对象的时候不会立即关闭socket。

  (2)太多的实例影响性能

  (3)单例的HttpClient或者共享HttpClient实例,不遵守DNS 生存时间 (TTL) 设置。(这个问题我也不太明白,具体怎么重现这个问题,我下去再研究研究。)

HttpClientFactory这个小可爱,解决了上面的所有问题,他也是ASP.NET Core2.1最新特点之一,下面详细聊聊HttpClient存在的这些问题。

 

一、HttpClient存在的问题

  由于设计错误、bug 和文档不正确等因素, 导致在.Net中正确使用HttpClient 出奇的难。因此, 在生产环境中看起来正常工作的应用程序可能会在负载大的情况下产生性能和运行时故障的问题。

  为了理解我们为什么遇到这种情况, 我们首先要看另一个面向连接的类: SqlConnection。 这个类实现了IDisposable接口,所以绝大多数开发人员都是这样写的,实例如下:

  using (var con = new SqlConnection(connectionString)) {
    
con.open();
    
//use the connection here
  } //this closes the connection  

虽然,这个例子在解释HttpClient存在的问题不是很到位,但是使用这种方式,来写上面的代码,是没错的。如果你尝试这把这种模式应用到实现了IDisposable接口的HttpClient,则会遇到一些很奇怪的问题。具体的说,它会打开比实际需要更多的socket,加重了服务器的负载。此外使用using语句是不会关闭这些套接字的,相反,在应用程序停止使用它们时,会关闭几分钟。 

Connection Pooling

回到 SqlConnection 示例中, 大多数面向连接的资源都是有连接池的。当您 "打开 " 数据库连接时, 它首先检查池中是否有可用的、未使用的连接。如果它找到一个, 将重用它, 而不是创建一个新的连接。

同样, 当您 "关闭 " SqlConnection 它只是将连接释放到链接池中。最终, 一个单独的进程可能会关闭长时间未使用的连接。

HttpClient 不这样做。当您处理它时, 它将启动关闭它所控制的套接字的过程。这意味着下次有请求时, 您必须经过一个全新的连接周期。如果您的网络有很高的延迟或您的连接是安全的, 则这会特别痛苦, 因为后者需要新一轮的 SSL/TLS 协商。 

Closing a Socket Takes Four Minutes 

如上所述,关闭套接字不是一个快速的过程。 当你“关闭”套接字时,你真正在做的是将它置于TIME_WAIT状态。 Windows将在此状态下保持连接240秒,以防万一剩余的数据包仍在传输中。

这使您更有可能耗尽可用套接字的数量,从而导致运行时错误,例如“无法连接到远程服务器.System.Net.Sockets.SocketException:每个套接字地址只有一种用法(协议/ 网络地址/端口通常是允许的“。

下面我们来实践一下,看看真相: 

示例演示:(注意使用的是.Net Core 1.0)

640?wx_fmt=png

这将会打开10个请求,并以get的方式,去请求博客园,我们只打印出状态码。

输出结果:

640?wx_fmt=png

到这个地步,可能我们就会很高兴,搞定!闪人!,真的搞定了吗?我的小可爱,下面我们使用netstat 工具并查看运行它的机器上的套接字状态,我们将看到:

640?wx_fmt=png

640?wx_fmt=jpeg

看到没,我的应用程序已经执行完了,但是,仍然有很多链接在打开上面图示中的主机,它们都处于TIME_WAIT状态,这意味这我们在应用程序这边已经把链接关闭了,但是我们仍然在等待查看,是否有额外的数据包进来,使用这些链接。因为它们可能在网络的某个地方已经被延迟,下面我们来看一张TCT/IP图,该图引自(https://www4.cs.fau.de/Projects/JX/Projects/TCP/tcpstate.html)

640?wx_fmt=png

 

Windows将在此状态下保持连接240秒(由[HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters \ TcpTimedWaitDelay]设置)。 Windows可以快速打开新套接字的速度有限,因此如果您耗尽连接池,那么您可能会看到如下错误:

Unable to connect to the remote server
System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.

在谷歌搜索会给你一些关于减少连接超时的可怕建议。 事实上,当在服务器上运行着正确使用HttpClient或类似构造的应用程序时,减少超时可能会导致其他不利后果。 我们需要了解“正确”意味着什么,并去修复底层的问题而不是去修补机器级的变量。

如果我们共享一个HttpClient实例,那么我们可以通过重用它们来减少套接字的浪费:

640?wx_fmt=png

请注意,我们只为整个应用程序共享了一个HttpClient实例。 仍然可以正常工作(实际上由于套接字重用而快一点)。 Netstat现在只显示:

 640?wx_fmt=jpeg

好了,总结一下:在.Net Core 1.0之前的版本,使用的时候需要注意下面的两点:

(1)确保你的HttpClient 是 static

(2)不要丢弃或包装HttpClient 在一个using块中。

小弟我才疏学浅,有不对的地方可以指出来,共同探讨。其实,我们一直使用using把它包起来,也是没错的,是因为HttpClient实现了IDisposable ,但是HttpClient就比较特殊,这不怪我们,文档就是错误的。

 

二、HttpClientFactory in ASP.NET Core 2.1就解决了上面所有的问题

HttpClientFactory 这个小可爱,就解决了上面的所有问题,她也是ASP.NET Core 2.1中最新特点之一,有了她我们就不用关心如何创建HttpClient,又如何释放它。关于如何使用它,博客园中的有介绍的,我这里就不再讲述了。 

具体请参考:https://www.cnblogs.com/willick/p/9640589.html 

三、总结

到这里该系列文章的第一篇就讲完了,有不对的地方,还请大佬们能指出来,共同探讨,好了,希望对你有所帮助,该系列文章,每周末更新,爱看不看,哈哈哈~~~~~~ 

参考文章:

(翻译)https://www.infoq.com/news/2016/09/HttpClient

(翻译)https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

原文地址:https://www.cnblogs.com/runningsmallguo/p/9649601.html


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

640?wx_fmt=jpeg

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

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

相关文章

欧拉回路哈密顿回路

欧拉回路 总结 百度百科 混合图的欧拉回路 Fleury算法 Hierholzer算法 //寻找无向图的欧拉路径 #include<iostream> #include<vector> #include<stack> using namespace std; vector<int> g[1001]; int n,m,x,y,d[1001],s-1,t-1; bool vis[1001][100…

【CDQ分治】三维偏序(luogu 3801/金牌导航 CDQ分治-1)

三维偏序 luogu 3801 金牌导航 CDQ分治-1 题目大意 有n个元素&#xff0c;第i个元素有ai,bi,cia_i,b_i,c_iai​,bi​,ci​三个属性&#xff0c;设 f(i)表示满足aj⩽aia_j\leqslant a_iaj​⩽ai​且bj⩽bib_j \leqslant b_ibj​⩽bi​且cj⩽cic_j \leqslant c_icj​⩽ci​且…

P4929-[模板]舞蹈链(DLX)

正题 题目链接:https://www.luogu.com.cn/problem/P4929 题目大意 n∗mn*mn∗m的矩形有0/10/10/1&#xff0c;要求选出若干行使得每一列有且仅有一个111。 解题思路 精确覆盖问题指的是一个集合SSS和它的若干个子集集合TTT&#xff0c;要求选出TTT的一个子集使得里面的集合元…

最大子矩阵(普通和01)

文章目录普通矩阵&#xff08;单个矩阵值为任何数&#xff09;最大子段和扩展到二维情况01矩阵&#xff08;单个矩阵值为0或1&#xff09;代码&#xff1a;普通矩阵&#xff08;单个矩阵值为任何数&#xff09; 例题&#xff1a;POJ 1074 求出其中最大的子矩阵 答案是&#x…

自动化流程开源框架BotSharp

BotSharp是一款为方便构建智能对话机器人平台而开发的开源框架&#xff0c;最大的特点是所有模型算法都是基于.NET Core开发实现&#xff0c;甚至最基本的Penn Treebank分词标准&#xff0c;都重新用C#实现了。在机器学习python占绝对优势的时代算是不可多得的项目。该项目涉及…

二分图匹配

定义&#xff1a; 二分图&#xff1a;一个图被分成了两部分&#xff0c;相同的部分没有边 匹配&#xff1a;二分图G的子图M中&#xff0c;M的边集{E}中的任意两条边都不指向同一个顶点 极大匹配&#xff1a;在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹…

【整体二分】区间第k小(金牌导航 整体二分-1)

区间第k小 金牌导航 整体二分-1 题目大意 给出一个序列&#xff0c;有若干查询&#xff0c;每次查询给出l,r,k&#xff0c;让你求l~r这个区间的第k大 输入样例 7 3 1 5 2 6 3 7 4 2 5 3 4 4 1 1 7 3输出样例 5 6 3数据范围 1⩽n⩽105,1⩽m⩽50000,1⩽∣ai∣⩽1091\leqsla…

积极参与开源项目,促进.NET Core生态社区发展

今天早上在微信群里聊天聊到百度的SDK 已经支持.NET Core, 百度已经在3月份就支持了&#xff0c;想起当时还是我在他们的github上提的issue&#xff1a; https://github.com/Baidu-AIP/dotnet-sdk/issues/3。.NET Core生态社区的发展已经四年多时间&#xff0c;日趋完善&#x…

P6091-[模板]原根

正题 题目链接:https://www.luogu.com.cn/problem/P6091 题目大意 给出一个数ppp&#xff0c;求出它的所有在[0,p][0,p][0,p]的原根。 解题思路 原根的定义&#xff0c;δp(a)\delta_p(a)δp​(a)表示一个最小的nnn使得an≡1(modp)a^n\equiv1(mod\ p)an≡1(mod p)&#xff0…

并查集小记

有什么用&#xff1a; 查询元素a和元素b是否属于同一组 合并元素a和元素b所在组 代码实现&#xff1a; #include<iostream> using namespace std; int n,m,p; int fa[5001]; int find(int x){if(fa[x]x) return x;else{return fa[x]find(fa[x]);} } int main(){cin&g…

Poj 1011 UVA - 307 Sticks

牛客网 poj 1011 题目&#xff1a; George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long th…

HAPPY2020暑假训练前复习

A.计蒜客 - T1381 输出hello world 万恶之源 B.51Nod - 2060 全排列输出 不要用STL的next_permutation,会超时 #include <bits/stdc.h> using namespace std; const int maxn14; int dt[maxn]; int vis[maxn];int n; void dfs(int depth) {if(depthn){for(int i0;; i…

【LCT】洞穴勘测(luogu 2147/金牌导航 LCT-1)

洞穴勘测 luogu 2147 金牌导航 LCT-1 题目大意 给你若干操作&#xff0c;有三种操作&#xff1a; 1.连接两个点 2.吧两个点之间的连边断掉&#xff08;保证有这条边&#xff09; 3.查询两个点之间是否连通 样例 #1 输入样例 #1 200 5 Query 123 127 Connect 123 127 Que…

Service Fabric 与Ocelot 的集成

概要云应用程序通常都需要使用前端网关&#xff0c;为用户、设备或其他应用程序提供同一个入口点。 在 Service Fabric 中&#xff0c;网关可以是任意无状态服务&#xff08;如 ASP.NET Core 应用程序&#xff09; 。本文介绍了如何将Ocelot用作 Service Fabric 应用程序的网关…

图论复习——最短路

知识点 最短路径算法 最短路径树 每个点uuu的父亲为使uuu得到最短距离的前驱节点&#xff0c;若有多个&#xff0c;则取任意一个。 题目 CF449B Jzzhu and Cities Blog CF464E The Classic Problem Blog [XSY3888] 传送门 对每个点uuu&#xff0c;记d(u)d(u)d(u)表示uuu…

Loj#143-[模板]质数判定【Miller-Rabin】

正题 题目链接:https://loj.ac/p/143 题目大意 给出一个数ppp&#xff0c;让你判定是否为质数。 解题思路 Miller−RabinMiller-RabinMiller−Rabin是一种基于费马小定理和二次探测定理的具有较高正确性的高效质数判定算法。 首先讲一下两个定理 费马小定理&#xff1a;gcd(…

【LCT】Tree II(luogu 1501)

Tree II luogu 1501 题目大意 给出一棵树&#xff0c;让你进行若干操作&#xff0c;操作如下&#xff1a; 1.把两个点路径上的所有点权值加k 2.把两个点路径上的所有点权值乘k 3.把一条边断开&#xff0c;连上另一条边 4.查询两个点路径上的权值和 输入样例 3 2 1 2 2 3 *…

图论复习汇总

三元环计数&四元环计数 Blog dfs树,点双,边双,强连通分量 Blog bfs树 对一个图运行 bfs 算法&#xff0c;每个点uuu的父亲定义为第一次遍历uuu时的前驱结点&#xff0c;若无则为根。 非树边只存在在同一层的两个点和相邻层的点中。 hihoCoder1147 时空阵 题意&#x…

P4718-[模板]Pollard-Rho算法

正题 题目链接:https://www.luogu.com.cn/problem/P4718 题目大意 给出一个数nnn&#xff0c;如果它是质数则输出PrimePrimePrime&#xff0c;否则输出它的最大质因子。 解题思路 Pollard-Rho\text{Pollard-Rho}Pollard-Rho算法的前置知识是Miller-Rabin\text{Miller-Rabin}M…

T-Dongle-S3开发笔记——创建工程

创建Hello world工程 打开命令面板 方法1&#xff1a;查看->命令面板 方法2&#xff1a;按F1 选择ESP-IDF:展示示例项目 创建helloworld 选择串口 选择芯片 至此可以编译下载运行了 运行后打印的信息显示flash只有2M。但是板子上电flash是W25Q32 4MB的吗 16M-bit