日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

HttpClientFactory的套路,你知多少?

發(fā)布時(shí)間:2023/12/4 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HttpClientFactory的套路,你知多少? 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

背景

ASP.NET Core 在 2.1 之后推出了具有彈性 HTTP 請(qǐng)求能力的 HttpClient 工廠類(lèi) HttpClientFactory。

替換的初衷還是簡(jiǎn)單擺一下:
① using(var client = new HttpClient()) 調(diào)用的 Dispose() 方法并不會(huì)立即釋放底層 Socket 連接,新建 Socket 需要時(shí)間,導(dǎo)致在高并發(fā)場(chǎng)景下 Socket 耗盡。
② 基于 ① 很多人會(huì)想到使用單例或者靜態(tài)類(lèi)構(gòu)造 HttpClient 實(shí)例,但是這里有一個(gè)坑,HttpClient 不會(huì)反應(yīng) DNS 的變更。

HttpClientFactory 以模塊化、可命名、可配置、彈性方式重建了 HttpClient 的使用方式:由 DI 框架注入 IHttpClientFactory 工廠;由工廠創(chuàng)建 HttpClient 并從內(nèi)部的 Handler 池分配請(qǐng)求 Handler。

HttpClient 可在 DI 框架中通過(guò)IHttpCLientBuilder對(duì)象配置 Policy 策略。

我一直對(duì)這種顛覆傳統(tǒng) HttpClient 的代碼組織方式感到好奇,今天我們帶著問(wèn)題來(lái)探究一下新版 HttpClient 的實(shí)現(xiàn)。

與碼無(wú)瓜

一個(gè)完整的 HttpClient 包括三部分:

  • 基礎(chǔ)業(yè)務(wù)配置:BaseAddress、DefaultRequestHeaders、DefaultProxy、TimeOut.....

  • 核心 MessageHandler:負(fù)責(zé)核心的業(yè)務(wù)請(qǐng)求

  • [可選的]附加 HttpMessageHandler

附加的 HttpMessageHandler 需要與核心 HttpMessageHandler 形成鏈?zhǔn)?Pipeline 關(guān)系,最終端點(diǎn)指向核心 HttpMessageHandler,
鏈表數(shù)據(jù)結(jié)構(gòu)是 DelegatingHandler 關(guān)鍵類(lèi)(包含 InnerHandler 鏈表節(jié)點(diǎn)指針)

刨瓜問(wèn)底

很明顯,HttpClientFactory 源碼的解讀分為 2 部分,心里藏著偽代碼,帶著問(wèn)題思考更香(手動(dòng)狗頭)。

P1. 構(gòu)建 HttpClient

在 Startup.cs 文件開(kāi)始配置要用到的 HttpClient

services.AddHttpClient("bce-request", x =>x.BaseAddress = new Uri(Configuration.GetSection("BCE").GetValue<string>("BaseUrl"))).ConfigurePrimaryHttpMessageHandler(_ => new BceAuthClientHandler(){AccessKey = Configuration.GetSection("BCE").GetValue<string>("AccessKey"),SerectAccessKey = Configuration.GetSection("BCE").GetValue<string>("SecretAccessKey"),AllowAutoRedirect = true,UseDefaultCredentials = true}).SetHandlerLifetime(TimeSpan.FromHours(12)).AddPolicyHandler(GetRetryPolicy(3));

配置過(guò)程充分體現(xiàn)了.NET Core 推崇的萬(wàn)物皆服務(wù),配置前移的 DI 風(fēng)格;
同對(duì)時(shí) HttpClient 的基礎(chǔ)、配置均通過(guò)配置即委托來(lái)完成

Q1. 如何記錄以上配置?

微軟使用一個(gè)HttpClientFactoryOptions對(duì)象來(lái)記錄 HttpClient 配置,這個(gè)套路是不是很熟悉?

  • 通過(guò) DI 框架的AddHttpClient擴(kuò)展方法產(chǎn)生 HttpClientBuilder 對(duì)象

  • HttpClientBuilder 對(duì)象的ConfigurePrimaryHttpMessageHandler擴(kuò)展方法會(huì)將核心 Handler 插到 Options 對(duì)象的 HttpMessageHandlerBuilderActions 數(shù)組,作為 Handlers 數(shù)組中的 PrimaryHandler

  • HttpClientBuilder 對(duì)象的AddPolicyHandler擴(kuò)展方法也會(huì)將 PolicyHttpMessageHandler 插到 Options 對(duì)象的 HttpMessageHandlerBuilderActions 數(shù)組,但是作為 AdditionHandler

// An options class for configuring the default System.Net.Http.IHttpClientFactorypublic class HttpClientFactoryOptions{public HttpClientFactoryOptions();// 一組用于配置HttpMessageHandlerBuilder的操作委托public IList<Action<HttpMessageHandlerBuilder>> HttpMessageHandlerBuilderActions { get; }public IList<Action<HttpClient>> HttpClientActions { get; }public TimeSpan HandlerLifetime { get; set; }public bool SuppressHandlerScope { get; set; }}

顯而易見(jiàn),后期創(chuàng)建 HttpClient 實(shí)例時(shí)會(huì)通過(guò) name 找到對(duì)應(yīng)的 Options,從中加載配置和 Handlers。

P2. 初始化 HttpClient 實(shí)例

通過(guò) IHttpClientFactory.CreateClient() 產(chǎn)生的 HttpClient 實(shí)例有一些內(nèi)部行為:
標(biāo)準(zhǔn)的 HttpClient(不帶 Policy 策略)除了 PrimaryHandler 之外,微軟給你附加了兩個(gè) AdditionHandler:

  • LoggingScopeHttpMessageHandler:最外圍 Logical 日志

  • LoggingHttpMessageHandler:核心 Http 請(qǐng)求日志

之后將排序后的 AdditionHanders 數(shù)組與 PrimaryHandler 通過(guò) DelegatingHandler 數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)化為鏈表, 末節(jié)點(diǎn)是 PrimaryHandler

輸出的日志如下:

Q2. 微軟為啥要增加外圍日志 Handler?

這要結(jié)合 P1 給出的帶 Policy 策略的 HttpClient,帶 Policy 策略的 HttpClient 會(huì)在 AdditionHandlers 插入 PolicyHttpMessageHandler 來(lái)控制retry、Circuit Breaker,那么就會(huì)構(gòu)建這樣的 Handler Pipeline:

所以微軟會(huì)在 AdditionHandlers 數(shù)組最外圍提供一個(gè)業(yè)務(wù)含義的日志 LogicalHandler,最內(nèi)層固定 LoggingHttpHandler,這是不是很靠譜?

無(wú)圖無(wú)真相,請(qǐng)查看帶Policy策略的 HttpClient 請(qǐng)求堆棧:

Q3. 何處強(qiáng)插、強(qiáng)行固定這兩個(gè)日志 Handler?
微軟通過(guò)在 DI 環(huán)節(jié)注入默認(rèn)的 LoggingHttpMessageHandlerBuilderFilter 來(lái)重排 Handler 的位置:

// 截取自LoggingHttpMessageHandlerBuilderFilter文件 public Action<HttpMessageHandlerBuilder> Configure(Action<HttpMessageHandlerBuilder> next) {return (builder) =>{next(builder);var loggerName = !string.IsNullOrEmpty(builder.Name) ? builder.Name : "Default";// We want all of our logging message to show up as-if they are coming from HttpClient,// but also to include the name of the client for more fine-grained control.var outerLogger = _loggerFactory.CreateLogger($"System.Net.Http.HttpClient.{loggerName}.LogicalHandler");var innerLogger = _loggerFactory.CreateLogger($"System.Net.Http.HttpClient.{loggerName}.ClientHandler");var options = _optionsMonitor.Get(builder.Name);// The 'scope' handler goes first so it can surround everything.builder.AdditionalHandlers.Insert(0, new LoggingScopeHttpMessageHandler(outerLogger, options));// We want this handler to be last so we can log details about the request after// service discovery and security happen.builder.AdditionalHandlers.Add(new LoggingHttpMessageHandler(innerLogger, options));}; }

Q4. 創(chuàng)建 HttpClient 時(shí),如何將 AdditionHandlers 和 PrimaryHandler 形成鏈?zhǔn)?Pipeline 關(guān)系 ?

protected internal static HttpMessageHandler CreateHandlerPipeline(HttpMessageHandler primaryHandler, IEnumerable<DelegatingHandler> additionalHandlers) {var additionalHandlersList = additionalHandlers as IReadOnlyList<DelegatingHandler> ?? additionalHandlers.ToArray();var next = primaryHandler;for (var i = additionalHandlersList.Count - 1; i >= 0; i--){var handler = additionalHandlersList[i];if (handler == null){var message = Resources.FormatHttpMessageHandlerBuilder_AdditionalHandlerIsNull(nameof(additionalHandlers));throw new InvalidOperationException(message);}handler.InnerHandler = next;next = handler;} }

數(shù)組轉(zhuǎn)鏈表IReadOnlyList<DelegatingHandler>的算法與 ASP.NET Core 框架的 Middleware 構(gòu)建 Pipeline 如出一轍。

總結(jié)

偽代碼演示實(shí)例創(chuàng)建過(guò)程:
DefaultHttpClientFactory.CreateClient()
--->構(gòu)造函數(shù)由 DI 注入默認(rèn)的 LoggingHttpMessageHandlerBuilderFilter
--->通過(guò) Options.HttpMessageHandlerBuilderActions 拿到所有的 Handlers
--->使用 LoggingHttpMessageHandlerBuilderFilter 強(qiáng)排 AdditionHandlers
--->創(chuàng)建 Handler 鏈?zhǔn)焦艿?br />--->用以上鏈?zhǔn)匠跏蓟?HttpClient 實(shí)例
--->從 Options.HttpClientActions 中提取對(duì)于 Httpclient 的基礎(chǔ)配置
--->返回一個(gè)基礎(chǔ)、HttpHandler 均正確配置的 HttpClient 實(shí)例

上述行為依賴(lài)于 ASP.NETCor 框架在 DI 階段注入的幾個(gè)服務(wù):

  • DefaultHttpClientFactory

  • LoggingHttpMessageHandlerBuilderFilter:過(guò)濾并強(qiáng)排 AdditionHandlers

  • DefaultHttpMessageHandlerBuilder:Handler數(shù)組轉(zhuǎn)鏈表

我們探究System.Net.Http庫(kù)的目的:
學(xué)習(xí)精良的設(shè)計(jì)模式、理解默認(rèn)的DI行為;
默認(rèn)DI行為給我們提供了擴(kuò)展/改造 HttpClientFactory 的一個(gè)思路:HttpClientFactory日志不好用,自己擴(kuò)展一個(gè)?

  • https://github.com/dotnet/extensions/blob/master/src/HttpClientFactory/Http/src/DependencyInjection/HttpClientFactoryServiceCollectionExtensions.cs

  • https://github.com/dotnet/extensions/blob/master/src/HttpClientFactory/Http/src/DefaultHttpClientFactory.cs

推薦閱讀

●?程序員應(yīng)對(duì)瀏覽器同源策略的姿勢(shì)

●?臨近年關(guān),修復(fù)ASP.NET Core因?yàn)g覽器內(nèi)核版本引發(fā)的單點(diǎn)登錄故障

●?ASP.NET Core跨平臺(tái)技術(shù)內(nèi)幕

●?TPL Dataflow組件應(yīng)對(duì)高并發(fā),低延遲要求

●?實(shí)例解讀Docker Swarm

●?基于docker-compose的Gitlab CI/CD實(shí)踐&排坑指南

總結(jié)

以上是生活随笔為你收集整理的HttpClientFactory的套路,你知多少?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久免费看 | 国产在线观看av | 成年人拍拍视频 | 一区二区三区四区欧美 | a久久久久久 | 在线观看日韩视频 | 天天色图片 | 蜜臀av夜夜澡人人爽人人 | 国产内射老熟女aaaa∵ | 久久香蕉影视 | 久久久精品人妻av一区二区三区 | 一级片在线观看免费 | 久久精品国内 | 日韩精品啪啪 | 亚洲精品一区中文字幕乱码 | 人妻丰满熟妇av无码区免 | 天天干天天摸天天操 | 中文字幕一区二区三区视频 | √天堂8资源中文在线 | 97香蕉久久超级碰碰高清版 | 午夜福利电影 | 日日干天天干 | 亚洲av无码国产精品色午夜 | 狠狠躁日日躁夜夜躁av | 久久精品欧美一区二区三区麻豆 | 亚洲色图20p | 一本一道久久a久久综合蜜桃 | 久久精品性爱视频 | 激情插插插 | 日韩免费视频网站 | 四虎在线视频免费观看 | 国产精品一二三四 | 日韩大胆视频 | 欧美一级一区 | 永久av免费在线观看 | 小泽玛利亚在线 | 国产污视频网站 | 五月婷婷欧美 | 夜夜撸小说| 国产20页 | 色妞在线 | 亚洲国产日韩精品 | 国产一区影院 | 九九在线观看高清免费 | 成年人免费网址 | 色在线综合 | 久操福利 | 日韩八区 | 国产原创av在线 | 黄色一区二区三区四区 | 久草高清 | 五月婷中文字幕 | 轻点好疼好大好爽视频 | 免费av看片| 国产性一乱一性一伧一色 | 欧美特一级片 | 欧美乱妇高清无乱码 | 99精品福利视频 | 国产精品入口夜色视频大尺度 | 国产裸体美女永久免费无遮挡 | 欧美人与性动交g欧美精器 国产在线视频91 | 五月天婷婷丁香 | 成人免费视屏 | 精品欧美一区二区在线观看 | 精品视频不卡 | 涩涩网址 | 91嫩草精品 | 欧美性生活| 国产精品一区二区三区四区在线观看 | 少妇综合网 | 小辣椒福利视频导航 | 91精品国产综合久久精品 | 致命弯道8在线观看免费高清完整 | 嫩模一区二区三区 | 欧美精品播放 | 日韩综合第一页 | 久久综合亚洲 | 精品国产午夜福利在线观看 | 成人a在线| 亚洲最大看欧美片网站 | 亚洲性激情 | 美女久久久久久久久久 | 亚洲人成色777777精品音频 | 日本人の夫妇交换 | 亚洲一区二区三区在线 | 国产97在线 | 亚洲 | 黄色一级视频在线观看 | 中文二区| 噜噜吧噜噜色 | 免费观看国产视频 | 国产综合在线视频 | 国产一区二区黑人欧美xxxx | 一区二区三区四区视频在线观看 | 欧美一级黄色片网站 | 国产91丝袜 | 少妇一级淫片免费看 | 婷婷中文字幕 | 午夜视频网站在线观看 | 午夜影院一区二区 |