# YARP Gateway - 租户路由网关 基于YARP的租户感知API网关,支持JWT解析、动态租户路由、加权负载均衡。 ## 功能特性 - ✅ JWT解析与Header传递 - ✅ 基于租户的动态路由 - ✅ 加权轮询负载均衡 - ✅ PostgreSQL配置持久化 - ✅ RESTful API管理接口 - ✅ Docker Compose部署 - ✅ Serilog结构化日志 - ✅ Prometheus指标导出 ## 架构设计 ``` 客户端请求 → JWT解析中间件 → 租户路由中间件 → YARP网关 → 后端微服务 ``` ### 路由流程 1. 客户端携带JWT访问 `/api/product/list` 2. JWT解析中间件提取租户ID(如 `customerA`) 3. 添加Header: `X-Tenant-Id: customerA` 4. 租户路由中间件根据路径提取服务名(`product`) 5. 动态构造Cluster ID: `customerA-product` 6. YARP将请求转发到该Cluster下的服务实例 7. 加权轮询策略选择实例 ## 快速开始 ### 前置要求 - .NET 10 SDK - PostgreSQL 16+ - Docker & Docker Compose(可选) ### 本地开发 1. **创建数据库** ```bash psql -h 192.168.100.10 -U postgres -c "CREATE DATABASE fengling_gateway;" ``` 2. **执行迁移** ```bash psql -h 192.168.100.10 -U postgres -d fengling_gateway -f sql/init.sql ``` 3. **运行网关** ```bash cd src/YarpGateway dotnet run ``` 4. **测试请求** ```bash # 生成测试JWT(需要配置Auth服务) # 然后测试请求 curl -H "Authorization: Bearer " \ http://localhost:8080/api/product/list ``` ### Docker部署 1. **启动所有服务** ```bash cd docker docker-compose up -d ``` 2. **查看日志** ```bash docker-compose logs -f gateway ``` 3. **停止服务** ```bash docker-compose down ``` ## API接口 ### 租户管理 **获取所有租户** ```http GET /api/gateway/tenants ``` **创建租户** ```http POST /api/gateway/tenants Content-Type: application/json { "tenantCode": "customerC", "tenantName": "客户C" } ``` **删除租户** ```http DELETE /api/gateway/tenants/{id} ``` ### 路由管理 **获取租户路由** ```http GET /api/gateway/tenants/{tenantCode}/routes ``` **创建路由** ```http POST /api/gateway/tenants/{tenantCode}/routes Content-Type: application/json { "serviceName": "product", "pathPattern": "/api/product/{**catch-all}" } ``` **删除路由** ```http DELETE /api/gateway/routes/{id} ``` ### 服务实例管理 **获取实例列表** ```http GET /api/gateway/clusters/{clusterId}/instances ``` **添加实例** ```http POST /api/gateway/clusters/{clusterId}/instances Content-Type: application/json { "destinationId": "product-3", "address": "http://customerA-product-3:8001", "weight": 2 } ``` **删除实例** ```http DELETE /api/gateway/instances/{id} ``` ### 配置热更新 ```http POST /api/gateway/reload ``` ## JWT格式要求 ### 必需Claims ```json { "tenant": "customerA", "sub": "123456", "unique_name": "张三", "role": ["admin", "user"] } ``` ### Header转换 JWT解析后,以下Header会自动添加到请求中: - `X-Tenant-Id`: 租户ID - `X-User-Id`: 用户ID - `X-User-Name`: 用户名 - `X-Roles`: 角色列表(逗号分隔) ## 负载均衡策略 ### 加权轮询 (WeightedRoundRobin) 权重高的实例获得更多流量分配。 **配置权重**: ```bash POST /api/gateway/clusters/customerA-product/instances { "destinationId": "product-1", "address": "http://customerA-product-1:8001", "weight": 10 # 权重10 } ``` **默认权重**: 1 ## 数据库表结构 ### gw_tenant 租户基础信息表 | 字段 | 类型 | 说明 | |------|------|------| | Id | BIGINT | 主键 | | TenantCode | VARCHAR(50) | 租户编码(唯一) | | TenantName | VARCHAR(100) | 租户名称 | | Status | INTEGER | 状态:1=启用 0=禁用 | ### gw_tenant_route 租户服务路由配置表 | 字段 | 类型 | 说明 | |------|------|------| | Id | BIGINT | 主键 | | TenantCode | VARCHAR(50) | 租户编码 | | ServiceName | VARCHAR(100) | 服务名称 | | ClusterId | VARCHAR(100) | YARP Cluster ID | | PathPattern | VARCHAR(200) | 路径匹配模式 | ### gw_service_instance 服务实例配置表 | 字段 | 类型 | 说明 | |------|------|------| | Id | BIGINT | 主键 | | ClusterId | VARCHAR(100) | Cluster ID | | DestinationId | VARCHAR(100) | Destination ID | | Address | VARCHAR(200) | 服务地址 | | Weight | INTEGER | 权重 | | Health | INTEGER | 健康状态:1=健康 0=不健康 | ## 监控和日志 ### 日志位置 - **控制台**: 实时输出 - **文件**: `logs/gateway-{Date}.log` ### Prometheus指标 默认导出到 `/metrics` 端点(需添加 Prometheus 包) **可用指标**: - `gateway_requests_total`: 请求总数(按租户、服务、状态码分组) - `gateway_request_duration_seconds`: 请求耗时(按租户、服务分组) ## 配置说明 ### appsettings.json ```json { "ConnectionStrings": { "DefaultConnection": "Host=postgres;Port=5432;Database=fengling_gateway;..." }, "Jwt": { "Authority": "https://your-auth-server.com", "Audience": "fengling-gateway" }, "ReverseProxy": { "Routes": { "catch-all-route": { ... } }, "Clusters": { "dynamic-cluster": { ... } } }, "Serilog": { ... } } ``` ### 环境变量 - `ConnectionStrings__DefaultConnection`: 数据库连接字符串 - `Jwt__Authority`: JWT认证服务器地址 - `Jwt__Audience`: JWT受众 ## 性能调优 ### 连接池配置 ```csharp services.AddDbContext(options => options.UseNpgsql(connectionString, o => { o.CommandTimeout(30); o.MaxBatchSize(100); })); ``` ### 日志级别优化 生产环境建议: ```json { "Logging": { "LogLevel": { "Default": "Warning", "Microsoft.AspNetCore": "Warning", "Yarp.ReverseProxy": "Information" } } } ``` ## 故障排查 ### 常见问题 **1. 路由404** - 检查 `gw_tenant_route` 表是否有对应路由配置 - 检查JWT中的tenant claim是否正确 **2. 数据库连接失败** - 验证连接字符串是否正确 - 检查PostgreSQL是否启动 - 检查防火墙设置 **3. 负载均衡不均** - 检查实例权重配置 - 检查实例健康状态 ## 项目结构 ``` src/YarpGateway/ ├── Config/ # 配置提供者 │ ├── JwtConfig.cs │ ├── DatabaseRouteConfigProvider.cs │ └── DatabaseClusterConfigProvider.cs ├── Controllers/ # API控制器 │ └── GatewayConfigController.cs ├── Data/ # 数据库上下文 │ └── GatewayDbContext.cs ├── LoadBalancing/ # 负载均衡策略 │ └── WeightedRoundRobinPolicy.cs ├── Middleware/ # 中间件 │ ├── JwtTransformMiddleware.cs │ └── TenantRoutingMiddleware.cs ├── Metrics/ # 监控指标 │ └── GatewayMetrics.cs ├── Models/ # 数据模型 │ ├── GwTenant.cs │ ├── GwTenantRoute.cs │ └── GwServiceInstance.cs ├── appsettings.json ├── Dockerfile └── Program.cs ``` ## 开发计划 - [ ] 添加Prometheus指标导出 - [ ] 实现Vue3管理界面 - [ ] 添加限流策略 - [ ] 添加熔断机制 - [ ] 实现配置中心集成 - [ ] 添加服务发现集成 ## 许可证 MIT License