docs: rewrite documentation from current implementation

This commit is contained in:
2026-07-30 13:30:24 +08:00
parent 5100854795
commit d895e1da63
23 changed files with 553 additions and 1612 deletions

160
docs/operations.md Normal file
View File

@@ -0,0 +1,160 @@
# 配置与后台任务
本文列出 API、DbMigrator 和 Worker 当前实际读取的配置。敏感值应通过环境变量、Secret Manager 或部署平台密钥注入,不能提交到仓库。
## 进程与依赖
| 进程 | PostgreSQL | Redis | RabbitMQ | 说明 |
| --- | --- | --- | --- | --- |
| `Tiku.Api` | 必需 | Development 可选Production 必需 | Development 可选Production 必需 | 提供 HTTP API、静态管理端、认证和 Outbox 发布 |
| `Tiku.Worker` | 必需 | Development 可选Production 必需 | Development 可选Production 必需 | 消费消息并轮询后台任务 |
| `Tiku.DbMigrator` | 必需 | 不需要 | 不需要 | 执行 Migration、内置目录 seed 和管理员引导 |
Development 未配置 Redis 时,安全服务使用进程内/数据库防线;未配置 RabbitMQ 时Worker 从 PostgreSQL 处理即时和延时任务。Production 不允许这两个降级模式。
## 数据库
解析顺序:
1. `ConnectionStrings:Database`
2. `DATABASE_URL`
3. 仅 Development`Host=localhost;Database=tiku;Username=<当前系统用户>`
DbMigrator 命令:
```bash
dotnet run --project Tiku.DbMigrator
dotnet ef migrations script \
--project Tiku.Infrastructure \
--startup-project Tiku.DbMigrator
dotnet ef migrations has-pending-model-changes \
--project Tiku.Infrastructure \
--startup-project Tiku.DbMigrator
```
Production 首次创建平台管理员必须显式执行:
```bash
export TIKU_BOOTSTRAP_PLATFORM_ADMIN_EMAIL='admin@example.com'
export TIKU_BOOTSTRAP_PLATFORM_ADMIN_PASSWORD='use-a-strong-temporary-password'
export TIKU_BOOTSTRAP_PLATFORM_ADMIN_NAME='Platform Administrator'
dotnet run --project Tiku.DbMigrator -- --bootstrap-platform-admin
```
该命令只允许在不存在平台角色用户绑定时执行。管理员首次登录后必须改密。
## Redis
连接串读取 `ConnectionStrings:Redis``REDIS_URL`。当前用途:
- 密码、短信发送和短信校验的跨实例安全窗口计数;
- 安全状态和租户 Feature 缓存失效;
- Production 的 ASP.NET Core Output Cache。
Redis key 使用环境前缀;配置解析会强制 `AbortOnConnectFail=false`。Redis 不是用户、Session、权限、套餐或用量的权威数据源。
## RabbitMQ 与 Outbox
配置节:
```json
{
"RabbitMq": {
"Host": "rabbitmq://localhost",
"VirtualHost": "/",
"Username": "guest",
"Password": "guest",
"OutboxBacklogAlertCount": 1000,
"OutboxOldestMessageAlertSeconds": 300
}
}
```
本地可用环境变量形式覆盖,例如 `RabbitMq__Host`。Production 必须同时提供有效 Host、Username 和 Password。
当前消息配置:
- kebab-case endpoint 名称;
- PostgreSQL EF Bus Outbox1 秒查询间隔;
- Consumer 端 EF inbox/outbox
- Consumer 单并发、prefetch 1
- 1、5、15 秒有限即时重试;
- 不使用 RabbitMQ delayed-message 插件,延时任务保留在 PostgreSQL。
API 只发布消息,不注册 ConsumerWorker 注册 `SecurityStateChangedConsumer``BackgroundJobRequestedConsumer`
## Worker 配置
```json
{
"TenantDomains": {
"Enabled": true,
"PollSeconds": 60,
"BatchSize": 50,
"DnsJsonEndpoint": "https://cloudflare-dns.com/dns-query",
"VerificationRecordPrefix": "_tiku-verification",
"AllowedCnameTargets": [],
"GatewayBaseUrl": null,
"GatewayApiKey": null
},
"SaasSubscriptions": {
"Enabled": true,
"BatchSize": 100,
"PastDueGraceDays": 7
},
"FeatureUsageReconciliation": {
"Enabled": true,
"BatchSize": 100,
"IntervalMinutes": 60
}
}
```
域名只有在 `AllowedCnameTargets`、DNS JSON endpoint、Gateway URL 和 API key 配置完成后,才可能从 Pending/Failed 进入 Active。仅 DNS 验证成功不代表 TLS 已就绪。
后台任务状态和 `RunAfter` 存在 PostgreSQL。Worker 使用租约并发处理;同一即时任务在启用 RabbitMQ 后不会同时进入消息 Consumer 和数据库即时轮询路径。
## 安全与网络配置
Production 启动至少需要核对:
| 配置 | 作用 |
| --- | --- |
| `Security:Jwt` | issuer、audience、当前 key ID、RSA 私钥和验证公钥 |
| `Security:DataProtection` | application name、X509 证书路径和密码 |
| `Security:TenantSecrets` | key ID 和 Base64 编码的 32 字节 master key |
| `Authentication:Sms` | 至少 32 字符的验证码 pepper 和频控阈值 |
| `Tenancy:Resolution` | 正式平台 Host、可信代理、tenant code 允许路径 |
| `AllowedHosts` | 非通配 Host allowlist |
| `Cors` | 明确的 Origin、Header、Method 和凭据策略 |
| `BrowserAuth:AllowedOrigins` | 允许使用 Browser Auth 的 HTTP(S) Origin |
| `RateLimiting` | 全局和认证端点限流 |
可用环境变量覆盖包括:
- `TIKU_DATA_PROTECTION_APPLICATION_NAME`
- `TIKU_DATA_PROTECTION_CERTIFICATE_PATH`
- `TIKU_DATA_PROTECTION_CERTIFICATE_PASSWORD`
- `TIKU_TENANT_SECRET_KEY_ID`
- `TIKU_TENANT_SECRET_MASTER_KEY`
- `TIKU_SMS_CODE_PEPPER`
不要在命令输出、文档、Git diff 或错误报告中粘贴这些值。
## 对象存储与外部 Provider
对象存储读取 `Storage` / `Storage:AliyunOss`,也支持 `STORAGE_*``ALIYUN_OSS_*` 环境变量。当前默认实现是阿里云 OSS并强制租户 key 前缀、上传大小和 MIME allowlist。
身份、短信、支付、通知和 AI 的租户配置由业务后台写入 `TenantExternalProvider`;敏感值写入加密的 `TenantSecret`。全局默认配置不能绕过租户 Provider 状态和 Secret 边界。
## 健康检查与观测
- `GET /api/health`:轻量 liveness只说明 API 进程可响应。
- `GET /api/health/ready`:检查 PostgreSQL、已配置 Redis、已配置 RabbitMQ并报告 Outbox pending、最老消息年龄和告警阈值依赖未就绪时返回 503。
- API 每 30 秒采样一次 Outbox backlog并暴露 `tiku.outbox.pending``tiku.outbox.oldest_age` meter。
- 设置 `OpenTelemetry:OtlpEndpoint` 后导出 ASP.NET Core、HTTP client 和数据库观测数据。
- Serilog 输出结构化请求日志;数据库性能拦截器记录慢查询指标。
Readiness 为绿色不等于认证授权、跨租户隔离或 Broker 恢复演练已通过,发布仍需执行对应集成测试。