世界速递!如何自动转发接收的请求报头? - 行业动态 -

当前位置:首页  >  行业动态  > 正文

世界速递!如何自动转发接收的请求报头?

世界速递!如何自动转发接收的请求报头?
2023-05-31 08:33:09 来源:博客园

了解OpenTelemetry的朋友应该知道,为了将率属于同一个请求的多个操作(Span)串起来,上游应用会生成一个唯一的TraceId。在进行跨应用的Web调用时,这个TraceId和代表跟踪操作标识的SpanID一并发给目标应用,W3C还专门指定了一份名为Trace Context的标准,该标准确定了一个名为trace-parent的请求报头来传递TraceId、(Parent)SpanID以及其他两个跟踪属性。其实我们的应用也可能会使用到分布式跟踪这种类似的功能,我们需要在某个应用中添加一些“埋点”,当它调用另一个应用时,这些埋点会自动添加到请求的报头集合中,从而实现在整个调用链中自动传递。为了实现这个功能,我创建了一个名为HeaderForwarder(Github)的框架。本文不会介绍HeaderForwarder的设计,仅仅介绍它的使用方式,有兴趣的朋友可以查看源代码。


(资料图片仅供参考)

一、 请求报头的自动转发二、 屏蔽自动转发功能三、 为请求添加请求报头四、 同名报头的处理五、 屏蔽“外部”添加的请求报头

一、 请求报头的自动转发

我们创建App1、App2和App3三个应用,ASP.NET Core应用App2和App3以路由的形式提供一个简单的API,App1则是一个简单的控制台应用。App1利用HttpClient调用App2承载的API,后者进一步调用App3。我们让处于中间的App2添加针对HeaderForwarder这个NuGet包的引用。如下所示的是控制台应用App1的定义。我们利用创建的HttpClient调用App2承载的API,发送的请求中人为添加了名为 “foo” 、“bar” 和 “baz” 的三个报头。

var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:5000/test");request.Headers.Add("foo", "123");request.Headers.Add("bar", "456");request.Headers.Add("baz", "789");using (var httpClient = new HttpClient()){    await httpClient.SendAsync(request);}

App2定义如下。HeaderForwarder设计的服务通过调用IServiceCollection接口的AddHeaderForwarder进行注册,该方法中同时指定了需要自动转发的报头名称 “foo” 和 “bar” (不区分大小写)。后面调用AddHttpClient扩展方法是为了使用注入的IHttpClientFactory对象所需的HttpClient对象。

var builder = WebApplication.CreateBuilder(args);builder.Services.AddHeaderForwarder("foo", "bar").AddHttpClient();var app = builder.Build();app.MapGet("/test", async (HttpRequest request, IHttpClientFactory httpClientFactory) =>{    foreach (var kv in request.Headers)    {        Console.WriteLine($"{kv.Key}:{kv.Value}");    }    await httpClientFactory.CreateClient().GetAsync("http://localhost:5001/test");});app.Run("http://localhost:5000");

App1调用的API体现为针对路径 “/test” 注册的路由。路由处理程序会再控制台上输出接收到的所有请求报头,并在此之后利用IHttpClientFactory对象创建的HttpClient完成针对App3的调用。App3提供的API仅仅按照如下的方式将接收到的请求报头输出到控制台上。

var app = WebApplication.CreateBuilder(args).Build();app.MapGet("/test",  (HttpRequest request) =>{    foreach (var kv in request.Headers)    {        Console.WriteLine($"{kv.Key}:{kv.Value}");    }});app.Run("http://localhost:5001");

三个应用先后启动后,App1调用App2添加的三个请求报头(“foo” 、 “bar” 和 “baz”)会出现在App2的控制台上。HeaderForwarder只会自动转发指定的请求报头“foo” 和“bar” ,所有只有这两个报头会出现在App3的控制台上。从图中还可以看到,默认由HttpClientFactory创建的HttpClient的调用添加和转发用于分布式跟踪的traceparent报头。

二、 屏蔽自动转发功能

HeaderForwarder能够获得当前的HttpContext上下文,并提取并转发所需的请求报头。如果App2在调用App3的时候并不希望将报头转发出去,可以按照如下的方式注入IOutgoingHeaderProcessor对象,并调用其SuppressHeaderForwarder方法将报头自动转发功能屏蔽掉。

using HeaderForwarder;var builder = WebApplication.CreateBuilder(args);builder.Services.AddHeaderForwarder("foo", "bar").AddHttpClient();var app = builder.Build();app.MapGet("/test", async (IHttpClientFactory httpClientFactory,IOutgoingHeaderProcessor processor ) =>{    using (processor.SuppressHeaderForwarder()){await httpClientFactory.CreateClient().GetAsync("http://localhost:5001/test");    }});app.Run("http://localhost:5000");

SuppressHeaderForwarder利用返回的IDisposable对象代表“屏蔽上下文”,意味着该创建的“屏障”会在其Dispose方法后失效,所以App2在此上下文中完成针对App3的调用,它接收的请求报头“foo” 和“bar”并不会被转发出去。

三、 为请求添加请求报头

当我们利用HttpClient进行Web调用时,如果需要认为地添加报头,典型的做法就是按照App1异常创建一个HttpRequestMessage对象,并将需要的报头以键值对的形式添加到它的Headers属性中。HeaderForwarder提供了一种更加快捷易用的编程模式。

var processor = OutgoingHeaderProcessor.Create();using(var httpClient = new HttpClient())using (processor.AddHeaders(("foo", "123"), ("bar", "456"), ("baz", "789")))await httpClient.GetAsync("http://localhost:5000/test");

如上面的代码片段所示,我们调用OutgoingHeaderProcessor类型的静态方法Create创建了一个IOutgoingHeaderProcessor对象,并调用其AddHeaders完成了三个请求报头的添加。这个方法同样返回一个通过IDisposable对象表示的执行上下文,在此上下文中针对HttpClient的调用生成的请求均会自动附加这三个报头。

四、 同名报头的处理

由于IOutgoingHeaderProcessor接口的AddHeaders方法返回的时一个IDisposable对象表示的上下文,意味着上下文之间可能出现嵌套的关系。在默认情况下,如果HttpClient在这样一个嵌套的上下文中被使用,这些上下文携带的请求报头都将被转发。一般来说,这种情况正是我们希望的,但是如果我们在一个具有嵌套关系的多个上下文中添加了多个同名的报头,就有可能出现我们不愿看到的结果。

using HeaderForwarder;var processor = OutgoingHeaderProcessor.Create();using(var httpClient = new HttpClient())await FooAsync(httpClient);async Task FooAsync(HttpClient httpClient){    using (processor.AddHeaders(("foobarbaz", "abc")))    await BarAsync(httpClient);}async Task BarAsync(HttpClient httpClient){    using (processor.AddHeaders(("foobarbaz", "abc")))    await BazAsync(httpClient);}async Task BazAsync(HttpClient httpClient){    using (processor.AddHeaders(("foobarbaz", "abc")))    await httpClient.GetAsync("http://localhost:5000/test");}

如上面的代码所示,三个嵌套调用的方法FooAsync、BarAsync和BazAsync采用相同的方式调用IOutgoingHeaderProcessor对象的AddHeaders方法添加相同的请求报头“foobarbaz”。意味着在BazAsync方法针对HttpClient的调用会在三个嵌套的上下文中进行,这意味着App2会接收到三个同名的请求报头。

如果不希望出现这种情况下,可以将针对AddHeaders方法的调用按照如下的方式替换成ReplaceHeaders。

async Task FooAsync(HttpClient httpClient){    using (processor.ReplaceHeaders(("foobarbaz", "abc")))    await BarAsync(httpClient);}async Task BarAsync(HttpClient httpClient){    using (processor.ReplaceHeaders(("foobarbaz", "abc")))    await BazAsync(httpClient);}async Task BazAsync(HttpClient httpClient){    using (processor.ReplaceHeaders(("foobarbaz", "abc")))    await httpClient.GetAsync("http://localhost:5000/test");}
五、 屏蔽“外部”添加的请求报头

如果不愿意收到嵌套的“外部”上下文的干扰,我们可以调用IOutgoingHeaderProcessor接口的AddHeadersAfterClear方法。顾名思义,这个方法在添加指定请求报头之前,会先将现有的报头清除。

var processor = OutgoingHeaderProcessor.Create();using(var httpClient = new HttpClient())await FooAsync(httpClient);async Task FooAsync(HttpClient httpClient){    using (processor.AddHeadersAfterClear(("foo", "123")))    await BarAsync(httpClient);}async Task BarAsync(HttpClient httpClient){    using (processor.AddHeadersAfterClear(("barbaz", "456")))    await BazAsync(httpClient);}async Task BazAsync(HttpClient httpClient){    using (processor.AddHeadersAfterClear(("barbaz", "789")))    await httpClient.GetAsync("http://localhost:5000/test");}

如上面的代码片段所示,FooAsync调用AddHeadersAfterClear方法添加了一个名为“foo”的报头,BarAsync和BazAsync则采用相同的方式添加了两个同名的请求报头“Barbaz”。App2只会接收到由BazAsync设置的报头。

AddHeadersAfterClear针对现有报头的清除只会体现在它创建的上下文中,当前上下文并不会收到影响。因为该方法根本没有做任何清除工作,而是创建一个全新的上下文。AddHeaders和ReplaceHeaders方法其实重用了外部的上下文。

标签:

(责任编辑:news01)
世界微速讯:山药为什么不能和鱼一起吃

世界微速讯:山药为什么不能和鱼一起吃

关于山药为什么不能和鱼一起吃的内容,包含山药为什么不能和鱼吃山药为什么不能和鱼一起吃山药为什么不能和
05-29 16:22:39
热点!一英镑等于多少人民币(2023年5月29日)

热点!一英镑等于多少人民币(2023年5月29日)

一英镑等于多少人民币,一英镑兑换多少人民币(2023年5月29日)金投外汇网行情中心每日更新。
05-29 15:54:36
今日播报!关于“礼让行人”该不该被取消及“礼让行人”该不该被取消详情

今日播报!关于“礼让行人”该不该被取消及“礼让行人”该不该被取消详情

音频解说1、你觉得该不该撤销礼让行人呢,对于不少车主而言,他们是弱势群体。2、在交通规章制度傍边,有一
05-29 14:58:10
俄媒:外国投资者出售在俄业务后累计撤资至少360亿美元

俄媒:外国投资者出售在俄业务后累计撤资至少360亿美元

俄罗斯央行上周发布的数据显示,2022年3月到2023年3月内,共有约200笔企业出售资产退出俄罗斯的交易,其中2
05-29 14:06:20
qq飞车加速挂下载2021 qq飞车加速挂

qq飞车加速挂下载2021 qq飞车加速挂

1、微加速,源于之前飞车的一款外挂,会微弱的提升赛车速度,真的是微弱,提升很少的,一般也就10-20km h。
05-29 13:24:32
交通银行网上缴费 交通银行网上缴费怎么退款 全球快播报

交通银行网上缴费 交通银行网上缴费怎么退款 全球快播报

本文内容是由小编为大家搜集关于交通银行网上缴费,以及交通银行网上缴费怎么退款的资料,整理后发布的内容
05-29 13:09:59
焦点快报!潘长江爆笑COS陈奕迅:要点全部到位 简直是灵 魂模仿

焦点快报!潘长江爆笑COS陈奕迅:要点全部到位 简直是灵 魂模仿

导读1、从潘长江戴假发cosplay陈奕迅的视频中来看,潘长江的模仿实在是惟妙惟肖,完全就抓住了陈奕迅那张照
05-29 11:30:52
大熊猫“丫丫”平安抵达北京动物园 现不对外展出 速讯

大熊猫“丫丫”平安抵达北京动物园 现不对外展出 速讯

大熊猫“丫丫”平安抵达北京动物园记者从北京动物园了解到,大熊猫“丫丫”顺利通过隔离检疫,乘坐中国...
05-29 11:16:24
天邦食品:5月26日融券卖出金额41.72万元,占当日流出金额的0.77%|当前焦点

天邦食品:5月26日融券卖出金额41.72万元,占当日流出金额的0.77%|当前焦点

同花顺数据中心显示,天邦食品5月26日获融资买入380 32万元,占当日买入金额的9 76%,当前融资余额4 77亿元
05-29 10:24:53
好离谱!王源妈妈看演唱会被拦门外,对保说“我是王源他妈”-天天百事通

好离谱!王源妈妈看演唱会被拦门外,对保说“我是王源他妈”-天天百事通

“笑死了,一群野生妈妈进场了,真正的妈妈被拦了”
05-29 09:44:38
企业如何自主训练AI?大数据行业首个大模型应用创新场景推出

企业如何自主训练AI?大数据行业首个大模型应用创新场景推出

摘要:以ChatGPT为代表的超大语言模型的迅速应用,加速了AI普及,那么企业如何训练适用性高的AI?  以Cha
05-29 08:53:56
中海油服:5月26日融券卖出金额14.17万元,占当日流出金额的0.61%

中海油服:5月26日融券卖出金额14.17万元,占当日流出金额的0.61%

同花顺数据中心显示,中海油服5月26日获融资买入199 34万元,占当日买入金额的11 59%,当前融资余额1 85亿
05-29 07:45:24
有趣的汉字小故事3篇10-20字简短_有趣的汉字小故事 世界焦点

有趣的汉字小故事3篇10-20字简短_有趣的汉字小故事 世界焦点

1、李鸿章是清末名臣。2、一次,他有个远房亲戚赴考,这个人不学无术,接到试卷一看,竟然一题也不会答。3
05-29 06:53:40
北京:6月起通勤班车及校车可使用公交专用道

北京:6月起通勤班车及校车可使用公交专用道

北京市公交专用道优化调整措施将于6月1日起实施,调整内容包括,经政府相关部门核定的单位通勤班车、校车允
05-29 05:56:15
脚踝扭伤肿了怎么消肿几天能好可以去上学吗_脚踝扭伤肿了怎么消肿|快播

脚踝扭伤肿了怎么消肿几天能好可以去上学吗_脚踝扭伤肿了怎么消肿|快播

1、病情分析:您的情况是可以走路的,适当活动可以促进血液循环,还可以用外用药和口服活血化瘀药物帮助消
05-29 04:07:50
环球速看:北华航天工业学院分数线多少_北华航天工业学院分数线

环球速看:北华航天工业学院分数线多少_北华航天工业学院分数线

1、接近二本线这几年可能比二本低的多一点不过最多也就比二本低二十多分。本文到此分享完毕,希望对大家有
05-29 03:15:53
世界速看:淇县有殷三仁祠将至卫辉有殷太师比干墓庙(关于淇县有殷三仁祠将至卫辉有殷太师比干墓庙介绍)

世界速看:淇县有殷三仁祠将至卫辉有殷太师比干墓庙(关于淇县有殷三仁祠将至卫辉有殷太师比干墓庙介绍)

来为大家讲解以上的问题。淇县有殷三仁祠将至卫辉有殷太师比干墓庙,县有殷三仁祠将至卫辉有殷太师比干墓庙
05-29 01:03:28
hkc显示器(hkc是什么牌子)

hkc显示器(hkc是什么牌子)

来为大家解答以下的问题,kc显示器,hkc是什么牌子这个很多人还不知道,现在让我们一起来看看吧!1、HKC“惠
05-28 23:18:03
《天宫课堂》线上课程|“高”端运动—微重力抗阻装置

《天宫课堂》线上课程|“高”端运动—微重力抗阻装置

《天宫课堂》线上课程系列,第二节课为大家介绍“高”端运动—微重力抗阻装置。再结合太空跑台、自行车...
05-28 22:06:03
高质量发展调研行|上海基础研究特区“特”在哪

高质量发展调研行|上海基础研究特区“特”在哪

如何加强基础研究,激发广大科研工作者的创新热情,从源头和底层解决关键技术问题,上海首创了基础研究特区
05-28 20:53:30
iphone过热警告是多少度_iphone高温警告是多少度[多图]

iphone过热警告是多少度_iphone高温警告是多少度[多图]

我们在使用手机的时候,如果一直使用容易发烫,那iphone过热警告是多少度?一起来看看吧~
05-28 19:53:10
当前热讯:罗体:憎恶那不勒斯和K77,一名罗马房东拒绝租房给格鲁吉亚游客

当前热讯:罗体:憎恶那不勒斯和K77,一名罗马房东拒绝租房给格鲁吉亚游客

罗体:憎恶那不勒斯和K77,一名罗马房东拒绝租房给格鲁吉亚游客,罗马,米兰,意甲,那不勒斯,格鲁吉亚,佛罗伦萨
05-28 19:16:31
【时快讯】抖音上我在江南撒把欢多无邪是哪首歌_我在江南撒把欢多无邪歌词全文

【时快讯】抖音上我在江南撒把欢多无邪是哪首歌_我在江南撒把欢多无邪歌词全文

欢迎观看本篇文章,小升来为大家解答以上问题。抖音上我在江南撒把欢多无邪是哪首歌,我在江南撒把欢多无邪
05-28 17:42:07
C919全球首次商业载客起飞!近130名旅客尝鲜,“国产大飞机靠它带头”-快报

C919全球首次商业载客起飞!近130名旅客尝鲜,“国产大飞机靠它带头”-快报

本文来源:时代财经作者:何铭亮张汀雯2023年5月28日,上海白天最高气温31度,虹桥机场也迎来万里晴空。上
05-28 17:10:54
成都大运会点燃全民运动热潮,引领市民由观赛人群转变为参赛人群

成都大运会点燃全民运动热潮,引领市民由观赛人群转变为参赛人群

封面新闻记者易弋力成都大运会将于7月28日正式拉开帷幕。自大运会筹备以来,成都将“大运惠民”贯彻始终...
05-28 16:04:06
薛之荔家的n次方_薛之荔 环球观天下

薛之荔家的n次方_薛之荔 环球观天下

1、高露曾出演《与青春有关的日子》《英雄无泪》《七剑下天山》《要案组雷霆出击》《刁蛮公主》。本文到此
05-28 14:50:05
许多年以后歌词表达意思_许多年以后 歌词 环球最资讯

许多年以后歌词表达意思_许多年以后 歌词 环球最资讯

1、时间过得太快不会再重来而我渐渐明白爱需要关怀其实我也害怕被你伤害经常对着电视机发呆可我依然相信我
05-28 13:11:51
王建硕博客_王建硕 焦点报道

王建硕博客_王建硕 焦点报道

1、你好!王建硕的拼音是什么?王建硕的拼音是:王建硕wángjiànshuò如有疑问。2、请追问。本文到此分享完
05-28 12:15:43
临沂水务集团董事长左囯栋接受有偿陪侍?临沂市纪委监委:情况属实

临沂水务集团董事长左囯栋接受有偿陪侍?临沂市纪委监委:情况属实

本文转自【琅琊新闻网】;记者从有关部门了解到,对网络举报的临沂水务集团董事长左囯栋接受有偿陪侍问题,
05-28 11:02:43
环球头条:驾车致人死亡怎样判刑?

环球头条:驾车致人死亡怎样判刑?

关于醉酒驾车致人死亡怎么判刑根据刑法第133条的规定;对交通肇事罪规定了三个不同的刑级(量刑档次):1、
05-28 10:00:37

为您推荐

精彩推送