fengling-console/README.md

371 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 <JWT_TOKEN>" \
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<GatewayDbContext>(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