作者 GitiJun 2019.08.19 09:31:48 写了58篇文章,回复33人, HttpClient引发的相关问题 阅读:2079· 评论:1· 喜欢:2 # 背景 由于一个项目里需要中转HTTP接口,在应用过程中出现请求慢的情况,首先发生在XXX内服务器上,以控制台直接运行,没有发生,但是以win服务运行,则会出现慢情况,而且时间都在3秒以上,无法忍受。此种情况在XXXXXX服务器上同样发生,奇怪的是在阿里云上同样部署没有这种情况。由此进行一系列的解决方案的寻找,当然首先是要定位问题。 # 寻源 在HTTP请求慢的情况中,可能存在几种情况,主要以HttpClient相关知识点展开,含RestSharper。 1. 改用HttpClientFactory一种尝试,在我们的这个慢场景中,仍无法完美解决。 Microsoft 在.Net Framework 4.5中引入了HttpClient,并且是在.NET服务器端代码中使用Web API的最常用方法。但它有一些严重的问题,如释放HttpClient对象不立即关闭套接字,太多实例影响性能和单个的HttpClient或共享HttpClient实例不尊重DNS生存时间(TTL)设置。HttpClientFactory解决了所有这些问题。它是ASP.NET Core 2.1的最新功能之一。本文主要介绍在ASP.NET Core 2.1中使用HTTPClientFactory的3种方法。 1、直接使用HttpClientFactory 2、通过HttpClient名字调用HttpClientFactory 3、使用自定义类执行HttpClientFactory请求 4、完全封装HttpClient可以使用下面方法 > 参见 ASP.NET Core 2.1 HTTPClientFactory使用的3种方法-CJavaPy https://www.cjavapy.com/article/150/ > .NET Core 2.1中的HttpClientFactory最佳实践 - zock - 博客园 https://www.cnblogs.com/atree/p/netcore-HttpClientFactory.html 2. 在.Net Core中使用HttpClient访问数据,除开因预热操作导致第一次访问缓慢的问题外,还存在预热完成后依旧缓慢的问题。排除目标服务器响应速度慢、业务逻辑异常后,可以进行如下尝试。 - 在构造HttpClient时可以使用HttpClient(HttpMessageHandler)构造函数,可以传入HttpMessageHandler的默认实现HttpClientHandler作为构造参数,也可以自行实现HttpMessageHandler。 - 传入构造参数前,将HttpClientHandler.UseProxy属性设置为false,禁用代理以提升每次使用HttpClient访问速度。 > 解决.Net Core中HttpClient响应慢的问题 – 墨意杂记 https://www.moetech.cn/software_development/54.html > 避免使用HttpClient的系统代理 - egmkang - 博客园 https://www.cnblogs.com/egmkang/p/7449575.html > 不简单的工厂:实际体验 .NET Core 2.1 新生物 HttpClientFactory – 前端开发,JQUERY特效,全栈开发,vue开发 https://www.jqhtml.com/43659.html > .NET HttpClient,存在缺陷让开发人员沮丧 - OSCHINA https://www.oschina.net/news/77036/httpclient > C#中遇到HttpClient耗时干扰问题_已解决_博问_博客园 https://q.cnblogs.com/q/96524/ # 源头总结或者澄清事实 1. HttpClient访问,预热操作会导致第一次访问缓慢。 2. 一些网络环境中使用了vpn/ss/ssr等工具后,如果使用默认代理,会导致请求延迟很高,即访问慢。此时需要禁用代理。 3. 请求中JSON序列化对访问慢的影响比例不会很大,仅很小比例,一般会几毫秒。虽然比例小,仍然有优化点的。 4. DNS解析可能会导致慢,但是占比会更小,几乎可以忽略,毫秒级。 5. 通过使用HttpClientfactory不需要考虑管理HttpClient的生命周期或担心遇到DNS问题。HttpClientfactory还有其他高级用法,例如和Polly的结合使用。 6. 默认情况下,每个新创建的HttpClientHandler(派生自HttpMessageHandler)生命周期只有2分钟。 7. 创建了很多HttpClient并使用到他们,你可以遇到Socket耗尽,而你基本上已经太快地使用了过多的Socket。您可以同时打开多个Socket是有限制的。当您dispose销毁HttpClient时,它打开的连接在TIME_WAIT状态下保持打开状态最长240秒(如果来自远程服务器的任何数据包仍然通过) 8. 每个请求都有自己的远程服务器连接池。这意味着您需要为每个创建的客户端支付重新连接到该远程服务器的成本。 9. 在 HttpClientFactory 出生之前,由于 HttpClient 臭名昭著的“dispose之后4分钟TCP连接才会被关闭”问题(详情),只能使用单例或静态的 HttpClient。但这会带来一个副作用,如果 dns 解析更新了,HttpClient 不会自动更新IP地址。原因是HttpClient不遵循DNS变化,它会(通过 HttpClientHandler)独占连接,直到套接字关闭。没有时间限制! 10. 在.NET Core的RC1和RC2版本之间,引入了一个Bug,导致HttpClient.Dispose调用会产生一个介于1010毫秒和1030毫秒之间的延迟。在.NET Core 1.2之前,这个问题预计不会得到修复。 11. Java中的HttpClient 4.0之后一个版本变一次API是要闹哪样啊...4.2.4用得好好的。 赞 | 2 赏 标签:none
学习了