fengling-platform/docs/yarp-configuration-model.md

10 KiB

YARP 配置模型分析

来源: microsoft/reverse-proxy
日期: 2026-03-03


核心概念

YARP (Yet Another Reverse Proxy) 的配置模型由三个核心接口/类组成:

  1. IProxyConfigProvider - 配置数据源接口
  2. IProxyConfig - 配置快照接口
  3. 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; }       // 配置变更通知
}

配置更新机制

  1. ChangeToken: 当配置发生变化时,ChangeToken 会触发通知
  2. RevisionId: 每次配置更新都会生成新的版本 ID
  3. 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. 参考资源