Fengling Console - 控制台后端
Go to file
2026-02-01 23:31:33 +08:00
.config chore(auth): upgrade OpenIddict to 7.2.0 2026-02-01 23:24:47 +08:00
.vscode chore(auth): upgrade OpenIddict to 7.2.0 2026-02-01 23:24:47 +08:00
docker chore(auth): upgrade OpenIddict to 7.2.0 2026-02-01 23:24:47 +08:00
docs feat(auth): upgrade all dependencies to latest versions 2026-02-01 23:31:33 +08:00
sql chore(auth): upgrade OpenIddict to 7.2.0 2026-02-01 23:24:47 +08:00
src feat(auth): upgrade all dependencies to latest versions 2026-02-01 23:31:33 +08:00
Fengling.Refactory.Buiding.sln chore(auth): upgrade OpenIddict to 7.2.0 2026-02-01 23:24:47 +08:00
OpenCode.md chore(auth): upgrade OpenIddict to 7.2.0 2026-02-01 23:24:47 +08:00
README.md chore(auth): upgrade OpenIddict to 7.2.0 2026-02-01 23:24:47 +08:00

YARP Gateway - 租户路由网关

基于YARP的租户感知API网关支持JWT解析、动态租户路由、加权负载均衡。

功能特性

  • JWT解析与Header传递
  • 基于租户的动态路由
  • 加权轮询负载均衡
  • PostgreSQL配置持久化
  • RESTful API管理接口
  • Docker Compose部署
  • Serilog结构化日志
  • Prometheus指标导出

架构设计

客户端请求 → JWT解析中间件 → 租户路由中间件 → YARP网关 → 后端微服务

路由流程

  1. 客户端携带JWT访问 /api/product/list
  2. JWT解析中间件提取租户IDcustomerA
  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. 创建数据库
psql -h 192.168.100.10 -U postgres -c "CREATE DATABASE fengling_gateway;"
  1. 执行迁移
psql -h 192.168.100.10 -U postgres -d fengling_gateway -f sql/init.sql
  1. 运行网关
cd src/YarpGateway
dotnet run
  1. 测试请求
# 生成测试JWT需要配置Auth服务
# 然后测试请求
curl -H "Authorization: Bearer <JWT_TOKEN>" \
  http://localhost:8080/api/product/list

Docker部署

  1. 启动所有服务
cd docker
docker-compose up -d
  1. 查看日志
docker-compose logs -f gateway
  1. 停止服务
docker-compose down

API接口

租户管理

获取所有租户

GET /api/gateway/tenants

创建租户

POST /api/gateway/tenants
Content-Type: application/json

{
  "tenantCode": "customerC",
  "tenantName": "客户C"
}

删除租户

DELETE /api/gateway/tenants/{id}

路由管理

获取租户路由

GET /api/gateway/tenants/{tenantCode}/routes

创建路由

POST /api/gateway/tenants/{tenantCode}/routes
Content-Type: application/json

{
  "serviceName": "product",
  "pathPattern": "/api/product/{**catch-all}"
}

删除路由

DELETE /api/gateway/routes/{id}

服务实例管理

获取实例列表

GET /api/gateway/clusters/{clusterId}/instances

添加实例

POST /api/gateway/clusters/{clusterId}/instances
Content-Type: application/json

{
  "destinationId": "product-3",
  "address": "http://customerA-product-3:8001",
  "weight": 2
}

删除实例

DELETE /api/gateway/instances/{id}

配置热更新

POST /api/gateway/reload

JWT格式要求

必需Claims

{
  "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)

权重高的实例获得更多流量分配。

配置权重

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

{
  "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受众

性能调优

连接池配置

services.AddDbContext<GatewayDbContext>(options =>
    options.UseNpgsql(connectionString, o =>
    {
        o.CommandTimeout(30);
        o.MaxBatchSize(100);
    }));

日志级别优化

生产环境建议:

{
  "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