Some checks failed
Build and Push Docker / build (push) Failing after 2m40s
- Update Fengling.Platform.Domain/Infrastructure from 1.0.14 to 1.0.17 - Add temporary EnsureDeletedAsync() to recreate Gateway DB tables - Fix bigint/character varying type mismatch in GwCluster.Id - Add Npgsql log level config to suppress GSSAPI warnings - Add DATABASE_SCHEMA_FIX.md documentation Refs: AGENTS.md Recent Changes 2026-03-08
173 lines
4.9 KiB
Markdown
173 lines
4.9 KiB
Markdown
# Gateway 数据库表结构修复文档
|
||
|
||
## 问题描述
|
||
|
||
### 错误现象
|
||
Gateway 服务启动时抛出异常:
|
||
```
|
||
Npgsql.PostgresException (0x80004005): 42883: operator does not exist: bigint = character varying
|
||
```
|
||
|
||
### 根本原因
|
||
1. `PlatformDbContext` 配置中 `GwCluster` 与 `GwDestination` 的关系外键类型不匹配
|
||
2. 旧版 `GwCluster.Id` 是 `long` (bigint),新版改为 `string` (varchar)
|
||
3. 数据库表结构是旧的(bigint),但代码已更新为新的实体定义(string)
|
||
|
||
### 影响范围
|
||
- fengling-gateway 服务无法加载路由配置
|
||
- YARP 代理功能无法正常工作
|
||
|
||
---
|
||
|
||
## 修复步骤
|
||
|
||
### 1. 更新 Platform 包版本
|
||
|
||
**文件**: `fengling-console/Directory.Packages.props`
|
||
|
||
```xml
|
||
<!-- 修改前 -->
|
||
<PackageVersion Include="Fengling.Platform.Domain" Version="1.0.14" />
|
||
<PackageVersion Include="Fengling.Platform.Infrastructure" Version="1.0.17" />
|
||
|
||
<!-- 修改后 -->
|
||
<PackageVersion Include="Fengling.Platform.Domain" Version="1.0.17" />
|
||
<PackageVersion Include="Fengling.Platform.Infrastructure" Version="1.0.17" />
|
||
```
|
||
|
||
### 2. 临时添加 EnsureDeletedAsync
|
||
|
||
**文件**: `fengling-console/src/Program.cs`
|
||
|
||
在初始化 Gateway 数据库前添加删除旧表逻辑:
|
||
|
||
```csharp
|
||
// 2. 初始化 Gateway 数据库(创建 GwRoutes, GwClusters 等表)
|
||
var gatewayDb = scope.ServiceProvider.GetRequiredService<PlatformDbContext>();
|
||
try
|
||
{
|
||
app.Logger.LogInformation("Deleting old Gateway database schema...");
|
||
await gatewayDb.Database.EnsureDeletedAsync(); // 临时:删除旧表结构
|
||
app.Logger.LogInformation("Initializing Gateway database...");
|
||
await gatewayDb.Database.EnsureCreatedAsync();
|
||
app.Logger.LogInformation("Gateway database initialized successfully");
|
||
}
|
||
```
|
||
|
||
### 3. 构建并部署
|
||
|
||
在 K3s 服务器 (192.168.100.120) 上执行:
|
||
|
||
```bash
|
||
cd /root/fengling/Fengling.Refactory.Pack
|
||
|
||
# 构建并推送新镜像
|
||
cd fengling-console/src
|
||
docker build -f Dockerfile -t 192.168.100.120:8418/fengling/console:test .
|
||
docker push 192.168.100.120:8418/fengling/console:test
|
||
|
||
# 重启 Console Pod(触发 EnsureDeleted + EnsureCreated)
|
||
kubectl rollout restart deployment/fengling-console -n fengling-test
|
||
|
||
# 观察日志,确认数据库表重建成功
|
||
kubectl logs -n fengling-test deployment/fengling-console -f
|
||
```
|
||
|
||
### 4. 验证修复
|
||
|
||
检查 Gateway 服务日志,确认路由加载成功:
|
||
|
||
```bash
|
||
# 重启 Gateway 加载新表结构
|
||
kubectl rollout restart deployment/fengling-gateway -n fengling-test
|
||
|
||
# 验证路由加载
|
||
kubectl logs -n fengling-test deployment/fengling-gateway | grep -i "loaded"
|
||
```
|
||
|
||
预期输出:
|
||
```
|
||
Loaded X routes from database
|
||
Loaded X clusters from database
|
||
```
|
||
|
||
### 5. 清理临时代码
|
||
|
||
修复成功后,移除 `EnsureDeletedAsync()` 避免数据丢失风险:
|
||
|
||
```bash
|
||
# 恢复 Program.cs(删除 EnsureDeletedAsync 行)
|
||
cd /root/fengling/Fengling.Refactory.Pack
|
||
git checkout fengling-console/src/Program.cs
|
||
# 或手动编辑删除 EnsureDeletedAsync 那一行
|
||
|
||
# 重新构建部署(不带删除逻辑)
|
||
cd fengling-console/src
|
||
docker build -f Dockerfile -t 192.168.100.120:8418/fengling/console:test .
|
||
docker push 192.168.100.120:8418/fengling/console:test
|
||
kubectl rollout restart deployment/fengling-console -n fengling-test
|
||
```
|
||
|
||
---
|
||
|
||
## 架构说明
|
||
|
||
### 数据库结构
|
||
|
||
```
|
||
fengling_gateway 数据库
|
||
├── GwRoutes (路由配置表)
|
||
│ ├── Id (string, PK)
|
||
│ ├── ServiceName (string)
|
||
│ ├── ClusterId (string, FK to GwClusters.ClusterId)
|
||
│ └── Match (jsonb)
|
||
│
|
||
└── ServiceInstances (集群配置表)
|
||
├── Id (string, PK)
|
||
├── ClusterId (string, Unique)
|
||
├── Name (string)
|
||
├── Destinations (Owned Collection)
|
||
│ ├── DestinationId (string)
|
||
│ ├── Address (string)
|
||
│ ├── TenantCode (string) -- 用于多租户路由
|
||
│ └── ...
|
||
└── ...
|
||
```
|
||
|
||
### 配置同步流程
|
||
|
||
```
|
||
K8s Service (Label: app-router-*)
|
||
↓
|
||
Console (K8sServiceWatchService)
|
||
↓
|
||
PendingConfigCache → User Confirm
|
||
↓
|
||
PostgreSQL (GwRoutes, ServiceInstances)
|
||
↓
|
||
PostgreSQL NOTIFY
|
||
↓
|
||
Gateway (PgSqlConfigChangeListener)
|
||
↓
|
||
YARP Route Reload
|
||
```
|
||
|
||
---
|
||
|
||
## 注意事项
|
||
|
||
1. **数据备份**: `EnsureDeletedAsync()` 会删除所有数据,生产环境务必先备份
|
||
2. **临时方案**: 此修复仅适用于测试环境,生产环境应使用 Migration
|
||
3. **多数据库**: Console 管理两个数据库:
|
||
- `fengling_console`: 身份认证、用户租户数据
|
||
- `fengling_gateway`: 网关路由配置(由 Console 写入,Gateway 读取)
|
||
|
||
---
|
||
|
||
## 相关文件
|
||
|
||
- `fengling-console/src/Program.cs` - 数据库初始化逻辑
|
||
- `fengling-console/Directory.Packages.props` - Platform 包版本
|
||
- `fengling-platform/Fengling.Platform.Infrastructure/PlatformDbContext.cs` - 实体配置
|
||
- `fengling-platform/Fengling.Platform.Domain/AggregatesModel/GatewayAggregate/` - 实体定义
|