前言YARP 与 .NET 10 的相遇YARPYet Another Reverse Proxy最初源于微软内部的一个现实困境大量内部团队在各自构建反向代理重复造轮子。微软决定将这些需求合并打造一个统一的高性能反向代理库。如今YARP 已经过规模化验证微软每天在生产中使用它处理数十亿次请求。在 .NET 10 时代YARP 作为 NuGet 包提供可运行于 Windows、Linux 和 macOS并已被正式纳入 ASP.NET Core 文档体系。整个接入过程只需三行代码builder.Services.AddReverseProxy().LoadFromConfig(builder.Configuration.GetSection(ReverseProxy));// ...app.MapReverseProxy();AddReverseProxy()负责向依赖注入容器注册 YARP 所需的全部服务.LoadFromConfig()从appsettings.json加载路由和集群配置app.MapReverseProxy()则将 YARP 中间件接入请求处理管道。但这三行背后究竟发生了什么让我们从源码出发逐层拆解。一、AddReverseProxy()的本质一个精心设计的 DI 编排器打开 GitHub 上dotnet/yarp仓库的ReverseProxyServiceCollectionExtensions.csAddReverseProxy()的完整实现如下publicstaticIReverseProxyBuilderAddReverseProxy(thisIServiceCollectionservices){varbuildernewReverseProxyBuilder(services);builder.AddConfigBuilder().AddRuntimeStateManagers().AddConfigManager().AddSessionAffinityPolicies().AddActiveHealthChecks().AddPassiveHealthCheck().AddLoadBalancingPolicies().AddDestinationResolver().AddProxy();if(OperatingSystem.IsWindows()){builder.AddHttpSysDelegation();}else{builder.Services.TryAddSingletonIHttpSysDelegator,DummyHttpSysDelegator();}services.TryAddSingletonProxyEndpointFactory();services.AddDataProtection();services.AddAuthorization();services.AddCors();services.AddRouting();returnbuilder;}这个方法做了两件事第一构建并返回IReverseProxyBuilder一个流式 API 的构建器第二通过九个内部子方法将整个代理系统所需的服务注入 DI 容器。返回值的意义不可忽视。AddReverseProxy()返回的是IReverseProxyBuilder而不是IServiceCollection这打破了常规的AddXxx()模式。这是有意为之的设计——它将 YARP 的扩展点从通用的服务集合中隔离出来给出一个专属的配置命名空间。所有后续的链式调用比如.LoadFromConfig()、.AddTransforms()、.ConfigureHttpClient()都是IReverseProxyBuilder的扩展方法而不是IServiceCollection的。二、九个子系统的逐一拆解2.1AddConfigBuilder()— 配置解析层这是路由配置的翻译器。它注册的核心服务负责将用户在appsettings.json或代码中定义的路由规则解析并编译成 YARP 内部使用的高效数据结构。具体来说它处理路由匹配规则Path、Headers、Methods 等的组合条件以及将RouteConfig转化为 ASP.NET Core 的Endpoint。2.2AddRuntimeStateManagers()— 运行时状态层YARP 的路由和集群状态都存储在内存中由运行时状态管理器维护。这一层注册的是IProxyStateLookup、RouteState、ClusterState、DestinationState等运行时对象的管理者。每一个集群下的目标节点DestinationState都携带健康状态、当前并发连接数等实时信息负载均衡算法基于这些数据做决策。2.3AddConfigManager()— 配置热重载层这是 YARP 最受欢迎的特性之一无需重启应用即可更新路由配置。IProxyConfigManager订阅IProxyConfigProvider的变更通知通过IChangeToken机制与IConfiguration的热重载体系打通当配置发生变化时它会原子性地替换内存中的路由和集群状态整个过程对进行中的请求是透明的。2.4 策略三件套AddSessionAffinityPolicies()/AddActiveHealthChecks()/AddPassiveHealthCheck()会话亲和Session Affinity确保同一客户端的请求始终路由到同一后端实例对需要本地状态的服务如 WebSocket 长连接、Server-Sent Events至关重要。YARP 内置基于 Cookie 和基于自定义请求头的两种亲和策略。主动健康检查Active Health Check由后台定时任务发起周期性地向每个目标的健康端点发送 HTTP 探针。如下配置启用了 10 秒一次的探测连续失败则标记该目标为不健康HealthCheck:{Active:{Enabled:true,Interval:00:00:10,Timeout:00:00:05,Policy:ConsecutiveFailures}}被动健康检查Passive Health Check则更为轻量它监听实际代理请求的结果当某个目标持续返回 5xx 或连接超时YARP 会将其临时标记为不健康并在ReactivationPeriod后重新尝试。这两种机制共同构成 YARP 的全面健康监控体系确保流量只被路由到健康的目标实例。2.5AddLoadBalancingPolicies()— 负载均衡层负载均衡策略通过AddLoadBalancingPolicies()在 DI 容器中注册并由UseLoadBalancing()中间件在MapReverseProxy()的默认管道中激活。如果没有指定策略默认使用PowerOfTwoChoices。内置策略包括策略名算法描述RoundRobin轮询均匀分发Random随机选择LeastRequests选择当前活跃请求数最少的目标PowerOfTwoChoices随机选两个取负载较低者默认FirstAlphabetical按名称排序优先第一个金丝雀发布场景你也可以实现ILoadBalancingPolicy接口来注入自定义策略通过PickDestination方法完全控制目标选择逻辑。2.6AddDestinationResolver()与AddProxy()— 核心转发层AddDestinationResolver()注册目标地址解析器。默认情况下目标地址是静态配置的但通过.AddDnsDestinationResolver()可以启用 DNS 动态解析适用于目标 IP 会变化的 Kubernetes 场景。AddProxy()是最核心的一步它注册了IHttpForwarderYARP 的 HTTP 转发引擎和ITransformBuilder请求/响应变换系统。HttpForwarder基于SocketsHttpHandler构建支持 HTTP/1.1、HTTP/2 和 HTTP/3并针对高并发进行了连接池优化。三、IReverseProxyBuilder链式 API 的扩展点全景3.1 配置加载两种模式声明式最常见builder.Services.AddReverseProxy().LoadFromConfig(builder.Configuration.GetSection(ReverseProxy));LoadFromConfig()注册了ConfigurationConfigProvider作为IProxyConfigProvider的单例实现通过闭包捕获IConfiguration对象并支持配置变更通知。编程式精确控制builder.Services.AddReverseProxy().LoadFromMemory(routes:new[]{newRouteConfig{RouteIdapi-route,ClusterIdapi-cluster,MatchnewRouteMatch{Path/api/{**catch-all}}}},clusters:new[]{newClusterConfig{ClusterIdapi-cluster,DestinationsnewDictionarystring,DestinationConfig{[node1]new(){Addresshttps://api1.internal/},[node2]new(){Addresshttps://api2.internal/}}}});更高级的场景可以实现IProxyConfigProvider接口从数据库、服务注册中心Consul、etcd或 Kubernetes API Server 动态拉取配置实现真正的服务发现集成。3.2 请求变换AddTransforms()变换Transforms是 YARP 中修改请求和响应的标准机制builder.Services.AddReverseProxy().LoadFromConfig(...).AddTransforms(ctx{// 全局添加 X-Forwarded-For 请求头ctx.AddXForwardedFor();// 对特定集群的请求注入自定义头if(ctx.Cluster?.ClusterIdinternal-cluster){ctx.AddRequestHeader(X-Internal-Token,secret,append:false);}// 自定义响应头处理ctx.AddResponseHeaderRemove(Server);});AddTransforms()可被多次调用每个回调独立注册为ITransformProvider的单例YARP 在处理每个路由时按注册顺序依次执行所有变换。对于更复杂的场景可以实现ITransformFactory来根据路由配置中的元数据动态生成变换逻辑。3.3 自定义 HTTP 客户端ConfigureHttpClient()builder.Services.AddReverseProxy().LoadFromConfig(...).ConfigureHttpClient((ctx,handler){// 为特定集群禁用 SSL 验证仅限内网场景if(ctx.NewConfig.ClusterIddev-cluster){handler.SslOptions.RemoteCertificateValidationCallback(_,_,_,_)true;}// 调整连接池参数handler.PooledConnectionLifetimeTimeSpan.FromMinutes(5);handler.MaxConnectionsPerServer100;});3.4 配置过滤器AddConfigFilterT()可通过AddConfigFilterT()注册多个IProxyConfigFilter过滤器它们按注册顺序运行可以在配置生效前对路由和集群进行动态修改或验证。这是实现多租户路由、基于环境变量动态调整目标地址等场景的利器。四、app.MapReverseProxy()— 中间件管道的激活AddReverseProxy()只是注册服务真正让代理运转的是app.MapReverseProxy()。它将 YARP 的中间件管道注册为 ASP.NET Core 路由系统中的一组Endpoint。默认管道包含以下中间件按顺序请求到达 ↓ SessionAffinity // 会话亲和性检查 ↓ LoadBalancing // 选择目标节点 ↓ PassiveHealthCheck // 监测响应结果更新健康状态 ↓ HttpForwarder // 实际 HTTP 转发 ↓ 响应返回你可以通过 lambda 参数完全自定义这条管道在任意位置插入自己的中间件app.MapReverseProxy(proxyPipeline{// 在转发前执行鉴权逻辑proxyPipeline.Use(async(context,next){varroutecontext.GetReverseProxyFeature().Route;// 根据路由元数据决定是否需要鉴权if(route.Config.Metadata?.ContainsKey(RequireAuth)true){if(context.User.Identity?.IsAuthenticated!true){context.Response.StatusCode401;return;}}awaitnext();});// 仍然启用默认的负载均衡proxyPipeline.UseLoadBalancing();});五、配置模型深度解析Routes 与 ClustersYARP 的配置围绕两个核心概念构建。Routes路由定义匹配规则Clusters集群定义后端目标集合它们通过ClusterId关联。一个完整的生产级配置示例{ReverseProxy:{Routes:{api-v2-route:{ClusterId:api-cluster,Match:{Path:/api/v2/{**catch-all},Headers:[{Name:X-API-Version,Values:[2],Mode:ExactHeader}]},Transforms:[{PathPattern:/v2/{**catch-all}},{RequestHeader:X-Forwarded-Host,Append:{host}}],Metadata:{RequireAuth:true}}},Clusters:{api-cluster:{LoadBalancingPolicy:LeastRequests,SessionAffinity:{Enabled:true,Policy:Cookie,AffinityKeyName:YARP-AFFINITY},HealthCheck:{Active:{Enabled:true,Interval:00:00:15,Timeout:00:00:05,Policy:ConsecutiveFailures,Path:/healthz},Passive:{Enabled:true,Policy:TransportFailureRate,ReactivationPeriod:00:02:00}},HttpClient:{MaxConnectionsPerServer:50,DangerousAcceptAnyServerCertificate:false},Destinations:{api-1:{Address:https://api-node1.internal:8080/,Health:https://api-node1.internal:8080/healthz},api-2:{Address:https://api-node2.internal:8080/,Health:https://api-node2.internal:8080/healthz}}}}}}六、与 ASP.NET Core 生态的深度集成AddReverseProxy()在最后调用了services.AddDataProtection()、services.AddAuthorization()、services.AddCors()和services.AddRouting()。这不是随意为之。AddAuthorization()使 YARP 路由可以直接配置AuthorizationPolicy借用 ASP.NET Core 的授权中间件保护代理端点无需重复实现。AddCors()允许在代理层统一处理 CORS 预检请求避免后端服务各自处理的复杂性。AddDataProtection()为会话亲和的 Cookie 提供加密和篡改防护。AddRouting()将 YARP 的路由规则整合进 ASP.NET Core 的端点路由系统可以与 Controller、Minimal API、SignalR 等端点共存同一个应用中互不干扰。与 JWT 鉴权的集成只需在AddReverseProxy()之前配置builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options{options.Authorityhttps://identity.example.com;options.Audienceproxy-api;});builder.Services.AddReverseProxy().LoadFromConfig(builder.Configuration.GetSection(ReverseProxy));// ...app.UseAuthentication();app.UseAuthorization();app.MapReverseProxy();七、生产实践建议可观测性优先。YARP 与 .NET 的ILogger、OpenTelemetry 和EventCounters深度集成。在生产环境中应至少配置对Yarp.ReverseProxy命名空间的结构化日志并通过 Prometheus 采集 YARP 暴露的性能计数器活跃请求数、转发成功率、P99 延迟等。合理利用{**catch-all}通配符。{**catch-all}模式使 YARP 能够转发所有子路径非常适合整段 API 路由的代理场景。但需注意过于宽泛的通配符可能意外捕获不希望代理的端点如/healthz或/metrics应通过路由优先级或更精确的路径匹配来规避。HttpClient 连接池调优。对于高并发场景SocketsHttpHandler的默认参数往往不够用。MaxConnectionsPerServer默认是无限制PooledConnectionIdleTimeout默认 2 分钟这在突发流量场景下容易导致连接数暴涨。建议根据实际 QPS 和后端容量显式配置这些参数。配置过滤器用于动态路由。在微服务场景中服务实例动态增减是常态。实现IProxyConfigProvider对接服务注册中心配合IChangeToken的变更通知可以在不重启应用的情况下实时更新路由表达到真正的零停机服务发现。结语builder.Services.AddReverseProxy()是一行代码但它背后是九个子系统的精密编排配置解析、状态管理、热重载、会话亲和、双模式健康检查、多策略负载均衡、目标解析以及基于SocketsHttpHandler的高性能 HTTP 转发引擎。YARP 的设计哲学是**“库而非框架”**——它被设计为可轻松定制和调整以满足每种部署场景特定需求的工具包而不是要求你通过脚本或重新编译来扩展的封闭系统。这正是它在微软内部、以及越来越多的生产系统中成为 API 网关首选的根本原因。对于 .NET 10 开发者而言YARP 已经不是可选项而是构建现代微服务架构时应当优先考虑的基础设施选择。