如何自动转发接收的请求报头实现高效网络通信?

摘要:了解OpenTelemetry的朋友应该知道,为了将率属于同一个请求的多个操作(Span)串起来,上游应用会生成一个唯一的TraceId。在进行跨应用的Web调用时,这个TraceId和代表跟踪操作标识的SpanID一并发给目标应用,W3C
了解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。如下所示的是控制台应用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仅仅按照如下的方式将接收到的请求报头输出到控制台上。
阅读全文