YARP 配置模型分析
来源: microsoft/reverse-proxy
日期: 2026-03-03
核心概念
YARP (Yet Another Reverse Proxy) 的配置模型由三个核心接口/类组成:
- IProxyConfigProvider - 配置数据源接口
- IProxyConfig - 配置快照接口
- RouteConfig / ClusterConfig - 路由和集群配置
┌─────────────────────────────────────────────────────────────┐
│ IProxyConfigProvider │
│ GetConfig() → IProxyConfig │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ IProxyConfig │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ RouteConfig[] │ │ ClusterConfig[] │ │
│ │ (路由规则) │ │ (集群配置) │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ ChangeToken: IChangeToken (配置变更通知) │
└─────────────────────────────────────────────────────────────┘
1. RouteConfig (路由配置)
路由定义了如何匹配传入请求并将其代理到集群。
核心字段
| 字段 |
类型 |
必填 |
说明 |
RouteId |
string |
✓ |
全局唯一路由标识 |
Match |
RouteMatch |
✓ |
请求匹配规则 |
ClusterId |
string |
○ |
目标集群 ID |
Order |
int? |
○ |
路由优先级 (数值越小优先级越高) |
AuthorizationPolicy |
string? |
○ |
授权策略名称 |
RateLimiterPolicy |
string? |
○ |
限流策略名称 |
TimeoutPolicy |
string? |
○ |
超时策略名称 |
CorsPolicy |
string? |
○ |
CORS 策略名称 |
MaxRequestBodySize |
long? |
○ |
请求体最大大小 |
Metadata |
IReadOnlyDictionary<string, string>? |
○ |
自定义元数据 |
Transforms |
IReadOnlyList<IReadOnlyDictionary<string, string>>? |
○ |
请求/响应转换规则 |
RouteMatch (匹配规则)
| 字段 |
类型 |
说明 |
Methods |
IReadOnlyList<string>? |
HTTP 方法列表 (GET, POST 等) |
Hosts |
IReadOnlyList<string>? |
Host 头匹配 (支持通配符) |
Path |
string? |
路径模式 (如 /api/{**catch-all}) |
Headers |
IReadOnlyList<RouteHeader>? |
请求头匹配规则 |
QueryParameters |
IReadOnlyList<RouteQueryParameter>? |
查询参数匹配规则 |
2. ClusterConfig (集群配置)
集群是一组等价的后端服务端点及其相关策略。
核心字段
| 字段 |
类型 |
必填 |
说明 |
ClusterId |
string |
✓ |
全局唯一集群标识 |
Destinations |
IReadOnlyDictionary<string, DestinationConfig>? |
○ |
目标端点字典 |
LoadBalancingPolicy |
string? |
○ |
负载均衡策略 |
SessionAffinity |
SessionAffinityConfig? |
○ |
会话亲和配置 |
HealthCheck |
HealthCheckConfig? |
○ |
健康检查配置 |
HttpClient |
HttpClientConfig? |
○ |
HTTP 客户端配置 |
HttpRequest |
ForwarderRequestConfig? |
○ |
出站请求配置 |
Metadata |
IReadOnlyDictionary<string, string>? |
○ |
自定义元数据 |
DestinationConfig (目标端点)
| 字段 |
类型 |
必填 |
说明 |
Address |
string |
✓ |
后端地址 (如 https://127.0.0.1:8080/) |
Health |
string? |
○ |
主动健康检查端点 |
Host |
string? |
○ |
Host 头值 |
Metadata |
IReadOnlyDictionary<string, string>? |
○ |
自定义元数据 |
3. 负载均衡策略
YARP 内置以下负载均衡策略:
| 策略名称 |
说明 |
RoundRobin |
轮询 |
LeastRequests |
最少请求 |
Random |
随机 |
PowerOfTwoChoices |
二选一 (推荐默认) |
First |
第一个 |
WeightedRoundRobin |
加权轮询 |
注意: WeightedRoundRobin 需要在 Destination 的 Metadata 中配置 Weight 字段。
4. 健康检查配置
HealthCheckConfig
public sealed record HealthCheckConfig
{
public PassiveHealthCheckConfig? Passive { get; init; } // 被动健康检查
public ActiveHealthCheckConfig? Active { get; init; } // 主动健康检查
public string? AvailableDestinationsPolicy { get; init; } // 可用目标策略
}
ActiveHealthCheckConfig (主动健康检查)
| 字段 |
类型 |
说明 |
Enabled |
bool? |
是否启用 |
Interval |
TimeSpan? |
检查间隔 |
Timeout |
TimeSpan? |
超时时间 |
Policy |
string? |
健康检查策略 |
Path |
string? |
健康检查路径 |
PassiveHealthCheckConfig (被动健康检查)
| 字段 |
类型 |
说明 |
Enabled |
bool? |
是否启用 |
Policy |
string? |
策略名称 |
ReactivationPeriod |
TimeSpan? |
重新激活周期 |
5. 会话亲和配置
SessionAffinityConfig
| 字段 |
类型 |
必填 |
说明 |
Enabled |
bool? |
○ |
是否启用 |
Policy |
string? |
○ |
策略 (Cookie, Header) |
FailurePolicy |
string? |
○ |
失败处理策略 |
AffinityKeyName |
string |
✓ |
亲和键名称 |
Cookie |
SessionAffinityCookieConfig? |
○ |
Cookie 配置 |
6. 动态配置更新
IProxyConfig 接口
public interface IProxyConfig
{
string RevisionId { get; } // 配置版本 ID
IReadOnlyList<RouteConfig> Routes { get; }
IReadOnlyList<ClusterConfig> Clusters { get; }
IChangeToken ChangeToken { get; } // 配置变更通知
}
配置更新机制
- ChangeToken: 当配置发生变化时,
ChangeToken 会触发通知
- RevisionId: 每次配置更新都会生成新的版本 ID
- YARP 内部: 监听
ChangeToken,触发时重新加载配置
实现动态更新的方式
public class CustomConfigProvider : IProxyConfigProvider
{
private volatile CustomProxyConfig _config;
public IProxyConfig GetConfig() => _config;
public void UpdateConfig(List<RouteConfig> routes, List<ClusterConfig> clusters)
{
var oldConfig = _config;
_config = new CustomProxyConfig(routes, clusters);
oldConfig.SignalChange(); // 触发 ChangeToken
}
}
7. 与现有实体的映射关系
GwTenantRoute → RouteConfig
| GwTenantRoute 字段 |
RouteConfig 字段 |
映射说明 |
Id |
RouteId |
直接映射 |
PathPattern |
Match.Path |
路径匹配模式 |
ClusterId |
ClusterId |
目标集群 |
Priority |
Order |
路由优先级 |
TenantCode |
Metadata["TenantCode"] |
租户标识 (元数据) |
ServiceName |
Metadata["ServiceName"] |
服务名称 (元数据) |
IsGlobal |
Metadata["IsGlobal"] |
全局路由标记 |
GwServiceInstance → DestinationConfig
| GwServiceInstance 字段 |
DestinationConfig 字段 |
映射说明 |
Address |
Address |
后端地址 |
Health |
Health |
健康检查端点 |
Weight |
Metadata["Weight"] |
权重 (加权负载均衡) |
DestinationId |
Dictionary Key |
目标字典的 Key |
多租户路由生成逻辑
for each GwTenantRoute:
routeId = $"{TenantCode}_{ServiceName}" or Id
routeConfig = new RouteConfig {
RouteId = routeId,
Match = new RouteMatch { Path = PathPattern },
ClusterId = ClusterId,
Order = Priority,
Metadata = { TenantCode, ServiceName, IsGlobal }
}
8. 实体结构对比与建议
当前实体 vs YARP 需求
| 方面 |
当前实体 |
YARP 需求 |
差异 |
| 路由匹配 |
只有 PathPattern |
Methods, Hosts, Headers, QueryParameters |
缺少高级匹配 |
| 负载均衡 |
无配置 |
LoadBalancingPolicy |
缺少策略配置 |
| 会话亲和 |
无配置 |
SessionAffinityConfig |
缺少会话保持 |
| 转换规则 |
无配置 |
Transforms |
缺少请求/响应转换 |
| 授权策略 |
无配置 |
AuthorizationPolicy |
缺少授权配置 |
| 限流 |
无配置 |
RateLimiterPolicy |
缺少限流配置 |
建议新增字段
GwTenantRoute 新增:
// 匹配规则扩展
public string? Methods { get; set; } // GET,POST,PUT
public string? Hosts { get; set; } // api.example.com
// 策略配置
public string? LoadBalancingPolicy { get; set; } // RoundRobin, WeightedRoundRobin
public string? AuthorizationPolicy { get; set; } // 授权策略
public string? RateLimiterPolicy { get; set; } // 限流策略
public string? CorsPolicy { get; set; } // CORS 策略
// 转换规则 (JSON)
public string? Transforms { get; set; } // 请求/响应转换
// 会话亲和
public bool SessionAffinityEnabled { get; set; }
public string? SessionAffinityPolicy { get; set; } // Cookie, Header
public string? SessionAffinityKeyName { get; set; }
GwServiceInstance 新增:
// 健康检查
public string? HealthCheckPath { get; set; } // /health
public int? HealthCheckInterval { get; set; } // 秒
// 主动健康检查端点
public string? HealthEndpoint { get; set; } // http://host:port/health
9. 参考资源