refactor: consolidate backend into modular monolith
This commit is contained in:
@@ -6,17 +6,17 @@
|
||||
|
||||
| 文档 | 内容 | 适合谁 |
|
||||
| --- | --- | --- |
|
||||
| [本地开发与运行](quickstart.md) | PostgreSQL 初始化、启动 API/Worker、验证命令、常见问题 | 新开发者 |
|
||||
| [系统架构与业务边界](architecture/overview.md) | 项目依赖、运行时组件、当前业务模块、请求与消息链路 | 开发与评审人员 |
|
||||
| [本地开发与运行](quickstart.md) | PostgreSQL 初始化、启动 API、验证命令、常见问题 | 新开发者 |
|
||||
| [系统架构与业务边界](architecture/overview.md) | 项目依赖、运行时组件、当前业务模块和后台任务链路 | 开发与评审人员 |
|
||||
| [认证、授权与租户隔离](architecture/security-and-tenancy.md) | 登录、Session、JWT、Cookie/CSRF、Realm、RBAC、Capability、DataScope、租户隔离 | API 与安全开发者 |
|
||||
| [配置与后台任务](operations.md) | 环境配置、Production 启动门禁、Redis/RabbitMQ、Worker、健康检查 | 开发与运维人员 |
|
||||
| [配置与后台任务](operations.md) | 环境配置、Production 启动门禁、Redis、Hosted Service、健康检查 | 开发与运维人员 |
|
||||
|
||||
## 权威来源
|
||||
|
||||
- API 契约:`Tiku.Api/Controllers`、请求/响应 DTO 和运行时 OpenAPI。
|
||||
- 数据模型:`Tiku.Domain`、`Tiku.Infrastructure/Persistence/Configurations` 和 EF Core Migration。
|
||||
- 认证授权:`Tiku.Api/Configuration`、`Tiku.Api/Middleware`、`Tiku.Application/Security`、`Tiku.Infrastructure/Security`。
|
||||
- 后台任务:`Tiku.Worker`、`Tiku.Application/Jobs`、`Tiku.Infrastructure/Jobs` 和 `Tiku.Infrastructure/Messaging`。
|
||||
- 后台任务:`Tiku.Api/BackgroundProcessing`、`Tiku.Application/Jobs` 和 `Tiku.Infrastructure/Jobs`。
|
||||
- 外部服务:Application 接口与 Infrastructure 实现;运行时租户配置存储在 `TenantExternalProvider` 和 `TenantSecret`。
|
||||
|
||||
## 维护规则
|
||||
|
||||
@@ -5,34 +5,30 @@
|
||||
## 分层与依赖
|
||||
|
||||
```text
|
||||
+------------------+
|
||||
| Tiku.Contracts |
|
||||
+--------^---------+
|
||||
|
|
||||
+-----------+ +---------------+---------------+
|
||||
| Tiku.Api | | Tiku.Worker / Tiku.DbMigrator |
|
||||
+-----+-----+ +---------------+---------------+
|
||||
| |
|
||||
+-------------+-------------+
|
||||
v
|
||||
+---------------------+
|
||||
| Tiku.Infrastructure |
|
||||
+----------+----------+
|
||||
v
|
||||
+---------------------+
|
||||
| Tiku.Application |
|
||||
+----------+----------+
|
||||
v
|
||||
+---------------------+
|
||||
| Tiku.Domain |
|
||||
+---------------------+
|
||||
+-------------------------+ +-----------------+
|
||||
| Tiku.Api | | Tiku.DbMigrator |
|
||||
| HTTP + Hosted Services | | Migrate + Seed |
|
||||
+------------+------------+ +--------+--------+
|
||||
| |
|
||||
+--------------+--------------+
|
||||
v
|
||||
+---------------------+
|
||||
| Tiku.Infrastructure |
|
||||
+----------+----------+
|
||||
v
|
||||
+---------------------+
|
||||
| Tiku.Application |
|
||||
+----------+----------+
|
||||
v
|
||||
+---------------------+
|
||||
| Tiku.Domain |
|
||||
+---------------------+
|
||||
```
|
||||
|
||||
- `Tiku.Domain` 保存领域实体、枚举和基础类型。除 Identity stores 抽象外,不依赖持久化或 Provider SDK。
|
||||
- `Tiku.Application` 定义用例契约、Provider 接口、安全上下文和业务目录,依赖 Domain。
|
||||
- `Tiku.Infrastructure` 实现 EF Core、PostgreSQL、Identity、外部 Provider、消息和后台任务,依赖 Application、Domain 与 Contracts。
|
||||
- `Tiku.Contracts` 保存 API 与 Worker 使用的版本化消息 DTO,不引用 HTTP、EF Core 或 Provider SDK。
|
||||
- `Tiku.Api`、`Tiku.Worker` 和 `Tiku.DbMigrator` 是独立运行入口。
|
||||
- `Tiku.Infrastructure` 实现 EF Core、PostgreSQL、Identity、外部 Provider 和后台任务,依赖 Application 与 Domain。
|
||||
- `Tiku.Api` 是唯一运行时入口,`Tiku.DbMigrator` 是部署时迁移和 seed 入口。
|
||||
|
||||
## 运行时组件
|
||||
|
||||
@@ -65,29 +61,29 @@ OpenAPI 和 Scalar 只在 Development 映射。平台管理端位于独立的 `T
|
||||
4. seed 内置 SaaS Feature、PermissionModule、BackendPermission 和 BackendMenu 目录。
|
||||
5. Development 全新数据库自动 seed 平台管理员;非 Development 仅在显式传入 `--bootstrap-platform-admin` 时创建管理员。
|
||||
|
||||
API 和 Worker 都不自动迁移数据库。
|
||||
API 不自动迁移数据库。
|
||||
|
||||
### Worker
|
||||
### API 后台处理
|
||||
|
||||
`Tiku.Worker` 当前注册四个独立 Hosted Service:
|
||||
`Tiku.Api` 在 `BackgroundProcessing:Enabled=true` 时注册四个 Hosted Service:
|
||||
|
||||
| Worker | 周期 | 当前职责 |
|
||||
| Hosted Service | 周期 | 当前职责 |
|
||||
| --- | --- | --- |
|
||||
| `TenantDomainWorker` | `TenantDomains:PollSeconds`,限制为 10~3600 秒 | 校验自定义域名 CNAME/TXT,调用网关 TLS 接口并失效租户缓存 |
|
||||
| `SaasSubscriptionWorker` | 60 秒 | 处理到期、宽限期等 SaaS 订阅生命周期 |
|
||||
| `FeatureUsageWorker` | `FeatureUsageReconciliation:IntervalMinutes`,限制为 1~1440 分钟 | 按真实业务数据校准租户 Feature 用量 |
|
||||
| `BackgroundJobsWorker` | 2 秒,4 个分区 | 租约处理 PostgreSQL 中的延时/待执行后台任务;未配置 RabbitMQ 时也处理即时任务 |
|
||||
| `TenantDomainBackgroundService` | `TenantDomains:PollSeconds`,限制为 10~3600 秒 | 校验自定义域名 CNAME/TXT,调用网关 TLS 接口并失效租户缓存 |
|
||||
| `SaasSubscriptionBackgroundService` | 60 秒 | 处理到期、宽限期等 SaaS 订阅生命周期 |
|
||||
| `FeatureUsageBackgroundService` | `FeatureUsageReconciliation:IntervalMinutes`,限制为 1~1440 分钟 | 按真实业务数据校准租户 Feature 用量 |
|
||||
| `BackgroundJobsBackgroundService` | 默认 2 秒、4 个分区 | 使用租约处理 PostgreSQL 中的即时、延时和待重试任务 |
|
||||
|
||||
后台任务当前支持 `content_import`、`content_export`、`statistics_aggregation`、`commerce_reconciliation` 和 `tenant_domain_recheck`。`asset_security_scan` 会明确失败,直到配置实际扫描 Provider;不能把它描述为已接通扫描服务。
|
||||
|
||||
配置 RabbitMQ 后,即时安全事件和后台任务请求使用 MassTransit;API 使用 EF Bus Outbox,Worker Consumer 使用 EF inbox/outbox。延时任务仍由 PostgreSQL `RunAfter` 和租约 Worker 处理。
|
||||
即时任务与 `RunAfter` 延时任务统一写入 `background_jobs`。Hosted Service 使用 `FOR UPDATE SKIP LOCKED` 认领任务,五分钟租约支持 API 重启后的恢复;当前生产部署按单 API 实例设计。
|
||||
|
||||
## 数据与持久化
|
||||
|
||||
- 数据库使用标准 PostgreSQL,普通 schema 由 EF Core entity、Fluent Configuration 和 Migration 管理。
|
||||
- 当前模型启用 `citext`、`ltree` 和 `pg_trgm` 扩展,并统一映射为 `snake_case`。
|
||||
- Data Protection key ring 由 API 持久化到 PostgreSQL;非 Development 必须使用 X509 证书保护。
|
||||
- MassTransit inbox/outbox 表与业务表处于同一 `TikuDbContext`。
|
||||
- 后台任务状态、执行时间、重试和结果由 `background_jobs` 持久化。
|
||||
- PostgreSQL 不启用 RLS;租户隔离由应用和数据库多层共同保证,详见[认证、授权与租户隔离](security-and-tenancy.md)。
|
||||
|
||||
## 当前业务模块
|
||||
|
||||
@@ -108,17 +108,14 @@ Development 默认平台 Host 是 `localhost` 和 `127.0.0.1`。Production 启
|
||||
|
||||
这些 guard 由 Migration helper 统一安装和移除,不允许在多份 Migration 中复制 SQL。
|
||||
|
||||
## System Scope 与可靠事件
|
||||
## System Scope 与后台处理
|
||||
|
||||
跨租户 Worker、迁移、seed 和平台级后台操作必须通过 `ITenantContextInitializer.InitializeSystem` 或受审计的 `ITenantExecutionScope` 进入 System Scope,并提供明确原因。业务代码不得直接关闭 Query Filter。
|
||||
跨租户 Hosted Service、迁移、seed 和平台级后台操作必须通过 `ITenantContextInitializer.InitializeSystem` 或受审计的 `ITenantExecutionScope` 进入 System Scope,并提供明确原因。业务代码不得直接关闭 Query Filter。
|
||||
|
||||
配置 RabbitMQ 时:
|
||||
|
||||
- API 使用 EF Bus Outbox,把业务写入、审计和消息放在同一数据库事务边界。
|
||||
- Worker Consumer 使用 EF inbox/outbox 和有限即时重试。
|
||||
- Session、成员、租户和套餐状态始终从 PostgreSQL 重新校验,不等待消息消费后才失效。
|
||||
- 延时/定时重试使用 PostgreSQL `RunAfter`,不依赖 RabbitMQ delayed-message 插件。
|
||||
- Session、成员、租户和套餐状态始终从 PostgreSQL 重新校验。
|
||||
- 租户、套餐和 Feature 变更在数据库提交后直接失效当前 API 进程与 Redis 中的相关缓存。
|
||||
- 后台任务在业务事务提交后持久化到 PostgreSQL,Hosted Service 使用租约执行;延时和重试由 `RunAfter` 控制。
|
||||
|
||||
## 安全配置门禁
|
||||
|
||||
Production 还会在启动时验证 Redis、RabbitMQ、Data Protection 证书、租户 Secret master key、短信 pepper、CORS 和外部服务配置。完整配置入口见[配置与后台任务](../operations.md)。
|
||||
Production 还会在启动时验证 Redis、Data Protection 证书、租户 Secret master key、短信 pepper、CORS 和外部服务配置。完整配置入口见[配置与后台任务](../operations.md)。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="1080" viewBox="0 0 1600 1080" role="img" aria-labelledby="title desc">
|
||||
<title id="title">TIKU Backend 当前技术架构图</title>
|
||||
<desc id="desc">TIKU Backend 是 ASP.NET Core 模块化单体。API、Worker 和 DbMigrator 共享 Application 契约、Infrastructure 实现以及 PostgreSQL、Redis、RabbitMQ 和外部服务。</desc>
|
||||
<desc id="desc">TIKU Backend 是 ASP.NET Core 模块化单体。API 承载 HTTP 与后台 Hosted Service,DbMigrator 负责迁移,运行时依赖 PostgreSQL、Redis 和外部服务。</desc>
|
||||
<defs>
|
||||
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto">
|
||||
<path d="M0 0L10 5L0 10Z" fill="#334155"/>
|
||||
@@ -148,18 +148,18 @@
|
||||
<text class="edge-label" x="844" y="418">实现 Application 接口并操作 Domain</text>
|
||||
|
||||
<!-- Processes -->
|
||||
<text class="group-title" x="1318" y="129">独立运行入口</text>
|
||||
<text class="group-title" x="1318" y="129">单体后台处理与迁移</text>
|
||||
<rect class="group" x="1310" y="145" width="250" height="570" rx="4"/>
|
||||
|
||||
<rect class="node-green" x="1336" y="180" width="198" height="192" rx="6"/>
|
||||
<circle class="badge" cx="1368" cy="211" r="18"/>
|
||||
<text class="badge-text" x="1368" y="211">W</text>
|
||||
<text class="node-title" x="1398" y="207">Tiku.Worker</text>
|
||||
<text class="badge-text" x="1368" y="211">BG</text>
|
||||
<text class="node-title" x="1398" y="207">API Hosted Services</text>
|
||||
<text class="node-text" x="1354" y="242">域名 DNS / TLS 生命周期</text>
|
||||
<text class="node-text" x="1354" y="269">SaaS 订阅生命周期</text>
|
||||
<text class="node-text" x="1354" y="296">Feature 用量校准</text>
|
||||
<text class="node-text" x="1354" y="323">后台任务租约执行</text>
|
||||
<text class="node-text" x="1354" y="350">RabbitMQ 消费者</text>
|
||||
<text class="node-text" x="1354" y="350">与 HTTP 共用 API 进程</text>
|
||||
|
||||
<rect class="node-amber" x="1336" y="408" width="198" height="144" rx="6"/>
|
||||
<circle class="badge" cx="1368" cy="439" r="18"/>
|
||||
@@ -177,7 +177,7 @@
|
||||
<path class="edge-dash" d="M1336 480H1242"/>
|
||||
|
||||
<!-- Data and external systems -->
|
||||
<text class="group-title" x="48" y="773">数据、消息与外部服务</text>
|
||||
<text class="group-title" x="48" y="773">数据与外部服务</text>
|
||||
<rect class="group" x="40" y="790" width="1520" height="212" rx="4"/>
|
||||
|
||||
<rect class="node-violet" x="70" y="826" width="270" height="138" rx="6"/>
|
||||
@@ -185,24 +185,24 @@
|
||||
<text class="badge-text" x="105" y="859">PG</text>
|
||||
<text class="node-title" x="139" y="854">PostgreSQL</text>
|
||||
<text class="node-text" x="92" y="892">EF Core 实体 / Identity / AuthSession</text>
|
||||
<text class="node-text" x="92" y="917">业务数据 / BackgroundJob / Outbox</text>
|
||||
<text class="node-text" x="92" y="917">业务数据 / BackgroundJob / Session</text>
|
||||
<text class="node-tiny" x="92" y="944">Query Filter · 写入拦截 · 数据库 Guard</text>
|
||||
|
||||
<rect class="node-violet" x="372" y="826" width="205" height="138" rx="6"/>
|
||||
<circle class="badge" cx="407" cy="859" r="20"/>
|
||||
<text class="badge-text" x="407" y="859">R</text>
|
||||
<text class="node-title" x="441" y="854">Redis</text>
|
||||
<text class="node-text" x="394" y="892">安全状态与失效广播</text>
|
||||
<text class="node-text" x="394" y="917">分布式缓存</text>
|
||||
<text class="node-text" x="394" y="892">安全频控</text>
|
||||
<text class="node-text" x="394" y="917">Feature / Output Cache</text>
|
||||
<text class="node-tiny" x="394" y="944">Production 必需</text>
|
||||
|
||||
<rect class="node-violet" x="609" y="826" width="225" height="138" rx="6"/>
|
||||
<circle class="badge" cx="644" cy="859" r="20"/>
|
||||
<text class="badge-text" x="644" y="859">MQ</text>
|
||||
<text class="node-title" x="678" y="854">RabbitMQ</text>
|
||||
<text class="node-text" x="631" y="892">MassTransit + EF Outbox</text>
|
||||
<text class="node-text" x="631" y="917">安全状态 / 后台任务消息</text>
|
||||
<text class="node-tiny" x="631" y="944">API 发布 · Worker 消费</text>
|
||||
<text class="badge-text" x="644" y="859">JOB</text>
|
||||
<text class="node-title" x="678" y="854">PostgreSQL 任务租约</text>
|
||||
<text class="node-text" x="631" y="892">即时任务 / RunAfter</text>
|
||||
<text class="node-text" x="631" y="917">SKIP LOCKED / 重试</text>
|
||||
<text class="node-tiny" x="631" y="944">API Hosted Service 执行</text>
|
||||
|
||||
<rect class="node-blue" x="866" y="826" width="205" height="138" rx="6"/>
|
||||
<text class="node-title" x="890" y="856">对象存储</text>
|
||||
@@ -232,5 +232,5 @@
|
||||
|
||||
<!-- Project dependency direction -->
|
||||
<rect class="boundary" x="40" y="1025" width="1520" height="38" rx="4"/>
|
||||
<text class="boundary-text" x="61" y="1050">项目依赖方向:Api → Application + Infrastructure | Worker → Application + Infrastructure | DbMigrator → Infrastructure | Infrastructure → Application + Domain + Contracts | Application → Domain</text>
|
||||
<text class="boundary-text" x="61" y="1050">项目依赖方向:Api → Application + Infrastructure | DbMigrator → Infrastructure | Infrastructure → Application + Domain | Application → Domain</text>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@@ -1,16 +1,15 @@
|
||||
# 配置与后台任务
|
||||
|
||||
本文列出 API、DbMigrator 和 Worker 当前实际读取的配置。敏感值应通过环境变量、Secret Manager 或部署平台密钥注入,不能提交到仓库。
|
||||
本文列出 API 和 DbMigrator 当前实际读取的配置。敏感值应通过环境变量、Secret Manager 或部署平台密钥注入,不能提交到仓库。
|
||||
|
||||
## 进程与依赖
|
||||
|
||||
| 进程 | PostgreSQL | Redis | RabbitMQ | 说明 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `Tiku.Api` | 必需 | Development 可选;Production 必需 | Development 可选;Production 必需 | 提供 HTTP API、静态管理端、认证和 Outbox 发布 |
|
||||
| `Tiku.Worker` | 必需 | Development 可选;Production 必需 | Development 可选;Production 必需 | 消费消息并轮询后台任务 |
|
||||
| `Tiku.DbMigrator` | 必需 | 不需要 | 不需要 | 执行 Migration、内置目录 seed 和管理员引导 |
|
||||
| 进程 | PostgreSQL | Redis | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `Tiku.Api` | 必需 | Development 可选;Production 必需 | 提供 HTTP API、认证、缓存和 Hosted Service 后台处理 |
|
||||
| `Tiku.DbMigrator` | 必需 | 不需要 | 执行 Migration、内置目录 seed 和管理员引导 |
|
||||
|
||||
Development 未配置 Redis 时,安全服务使用进程内/数据库防线;未配置 RabbitMQ 时,Worker 从 PostgreSQL 处理即时和延时任务。Production 不允许这两个降级模式。
|
||||
Development 未配置 Redis 时,安全服务使用进程内/数据库防线。Production 不允许 Redis 降级;后台任务在所有环境统一使用 PostgreSQL。
|
||||
|
||||
## 数据库
|
||||
|
||||
@@ -49,46 +48,22 @@ dotnet run --project Tiku.DbMigrator -- --bootstrap-platform-admin
|
||||
|
||||
连接串读取 `ConnectionStrings:Redis` 或 `REDIS_URL`。当前用途:
|
||||
|
||||
- 密码、短信发送和短信校验的跨实例安全窗口计数;
|
||||
- 安全状态和租户 Feature 缓存失效;
|
||||
- 密码、短信发送和短信校验的安全窗口计数;
|
||||
- 租户 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 Outbox,1 秒查询间隔;
|
||||
- Consumer 端 EF inbox/outbox;
|
||||
- Consumer 单并发、prefetch 1;
|
||||
- 1、5、15 秒有限即时重试;
|
||||
- 不使用 RabbitMQ delayed-message 插件,延时任务保留在 PostgreSQL。
|
||||
|
||||
API 只发布消息,不注册 Consumer;Worker 注册 `SecurityStateChangedConsumer` 和 `BackgroundJobRequestedConsumer`。
|
||||
|
||||
## Worker 配置
|
||||
## 后台处理配置
|
||||
|
||||
```json
|
||||
{
|
||||
"BackgroundProcessing": {
|
||||
"Enabled": true,
|
||||
"JobPollSeconds": 2,
|
||||
"JobParallelism": 4,
|
||||
"JobBatchSize": 5
|
||||
},
|
||||
"TenantDomains": {
|
||||
"Enabled": true,
|
||||
"PollSeconds": 60,
|
||||
@@ -114,7 +89,7 @@ API 只发布消息,不注册 Consumer;Worker 注册 `SecurityStateChangedCo
|
||||
|
||||
域名只有在 `AllowedCnameTargets`、DNS JSON endpoint、Gateway URL 和 API key 配置完成后,才可能从 Pending/Failed 进入 Active。仅 DNS 验证成功不代表 TLS 已就绪。
|
||||
|
||||
后台任务状态和 `RunAfter` 存在 PostgreSQL。Worker 使用租约并发处理;同一即时任务在启用 RabbitMQ 后不会同时进入消息 Consumer 和数据库即时轮询路径。
|
||||
后台任务状态和 `RunAfter` 存在 PostgreSQL。API Hosted Service 使用 `FOR UPDATE SKIP LOCKED`、五分钟租约和有限重试处理即时、延时及失败待重试任务。`BackgroundProcessing:Enabled=false` 会关闭全部四个后台循环,通常只用于测试或维护。
|
||||
|
||||
## 安全与网络配置
|
||||
|
||||
@@ -152,9 +127,14 @@ Production 启动至少需要核对:
|
||||
## 健康检查与观测
|
||||
|
||||
- `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。
|
||||
- `GET /api/health/ready`:检查 PostgreSQL 和已配置 Redis;依赖未就绪时返回 503。
|
||||
- 设置 `OpenTelemetry:OtlpEndpoint` 后导出 ASP.NET Core、HTTP client 和数据库观测数据。
|
||||
- Serilog 输出结构化请求日志;数据库性能拦截器记录慢查询指标。
|
||||
|
||||
Readiness 为绿色不等于认证授权、跨租户隔离或 Broker 恢复演练已通过,发布仍需执行对应集成测试。
|
||||
Readiness 为绿色不等于认证授权、跨租户隔离或后台任务恢复演练已通过,发布仍需执行对应集成测试。
|
||||
|
||||
## 从 RabbitMQ 版本切换
|
||||
|
||||
移除消息表的 Migration 与旧 API/Worker 不兼容。发布时使用维护窗口:停止旧 API 和 Worker,确认 RabbitMQ Consumer 已退出并备份 PostgreSQL,运行 `Tiku.DbMigrator`,再部署新 API。未消费的后台任务消息可丢弃,因为对应任务记录已经写入 `background_jobs`;安全消息不保存授权真相。
|
||||
|
||||
切换时不强制重置 `processing` 任务。旧租约最多五分钟后由新 API 接管。回滚需要先停止新 API,执行 Migration Down 重建空 inbox/outbox 表,再恢复 RabbitMQ 配置和旧 API/Worker;历史消息不会恢复。
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
可选:
|
||||
|
||||
- Redis 7;
|
||||
- RabbitMQ 4。
|
||||
|
||||
```bash
|
||||
dotnet --version
|
||||
@@ -89,29 +88,25 @@ dotnet run --project Tiku.Api
|
||||
|
||||
OpenAPI 和 Scalar 仅在 Development 映射。接口路径、输入字段、响应模型和授权要求以这里生成的文档为准。
|
||||
|
||||
## 6. 可选:启动 Redis 和 RabbitMQ
|
||||
## 6. 可选:启动 Redis
|
||||
|
||||
本地单实例开发可以不配置这两个依赖。需要验证分布式安全频控、Output Cache、消息和 Outbox 时,先启动本地服务,再设置:
|
||||
本地单实例开发可以不配置 Redis。需要验证安全频控、Feature 缓存和 Output Cache 时,先启动本地服务,再设置:
|
||||
|
||||
```bash
|
||||
export ConnectionStrings__Redis='localhost:6379,abortConnect=false'
|
||||
export RabbitMq__Host='rabbitmq://localhost'
|
||||
export RabbitMq__VirtualHost='/'
|
||||
export RabbitMq__Username='guest'
|
||||
export RabbitMq__Password='guest'
|
||||
```
|
||||
|
||||
RabbitMQ 使用 4.x,当前代码不依赖 delayed-message 插件。延时任务由 PostgreSQL `RunAfter` 调度。
|
||||
Production 必须配置 Redis;PostgreSQL 仍是用户、Session、权限、套餐和用量的权威数据源。
|
||||
|
||||
## 7. 可选:启动 Worker
|
||||
## 7. 后台处理
|
||||
|
||||
需要处理域名、订阅、用量或后台任务时,在另一个终端使用相同配置启动:
|
||||
API 默认在同一进程启动域名、订阅、用量和后台任务 Hosted Service。需要临时关闭时配置:
|
||||
|
||||
```bash
|
||||
dotnet run --project Tiku.Worker
|
||||
export BackgroundProcessing__Enabled=false
|
||||
```
|
||||
|
||||
Worker 会立即开始轮询。域名 DNS/TLS 流程只有在 `TenantDomains` 的 CNAME target 和 Gateway 配置完整后才能激活自定义域名。
|
||||
后台任务状态、租约、重试和 `RunAfter` 存在 PostgreSQL。域名 DNS/TLS 流程只有在 `TenantDomains` 的 CNAME target 和 Gateway 配置完整后才能激活自定义域名。
|
||||
|
||||
## 8. 开发验证
|
||||
|
||||
@@ -139,7 +134,7 @@ pg_isready -h 127.0.0.1 -p 5432
|
||||
psql -h 127.0.0.1 -U <数据库用户> -d postgres -c 'select current_user;'
|
||||
```
|
||||
|
||||
确认当前终端的 `DATABASE_URL` 指向真实存在的数据库,并且 API、DbMigrator 和 Worker 使用同一连接配置。
|
||||
确认当前终端的 `DATABASE_URL` 指向真实存在的数据库,并且 API 与 DbMigrator 使用同一连接配置。
|
||||
|
||||
### 无法创建 PostgreSQL 扩展
|
||||
|
||||
@@ -151,7 +146,7 @@ psql -h 127.0.0.1 -U <数据库用户> -d postgres -c 'select current_user;'
|
||||
|
||||
### Readiness 返回 503
|
||||
|
||||
检查响应中的 `database`、`redis.ready` 和 `rabbitMq.ready`。只配置了 Redis/RabbitMQ 连接串但服务未启动时,readiness 会按已配置依赖检查并返回 503。
|
||||
检查响应中的 `database` 和 `redis.ready`。配置了 Redis 连接串但服务未启动时,readiness 会返回 503。
|
||||
|
||||
### API 出现 HTTPS 重定向警告
|
||||
|
||||
|
||||
Reference in New Issue
Block a user