Files
zclaw_openfang/docs/knowledge-base/loco-rs-patterns.md
iven 8b9d506893 refactor(saas): 架构重构 + 性能优化 — 借鉴 loco-rs 模式
Phase 0: 知识库
- docs/knowledge-base/loco-rs-patterns.md — loco-rs 10 个可借鉴模式研究

Phase 1: 数据层重构
- crates/zclaw-saas/src/models/ — 15 个 FromRow 类型化模型
- Login 3 次查询合并为 1 次 AccountLoginRow 查询
- 所有 service 文件从元组解构迁移到 FromRow 结构体

Phase 2: Worker + Scheduler 系统
- crates/zclaw-saas/src/workers/ — Worker trait + 5 个具体实现
- crates/zclaw-saas/src/scheduler.rs — TOML 声明式调度器
- crates/zclaw-saas/src/tasks/ — CLI 任务系统

Phase 3: 性能修复
- Relay N+1 查询 → 精准 SQL (relay/handlers.rs)
- Config RwLock → AtomicU32 无锁 rate limit (state.rs, middleware.rs)
- SSE std::sync::Mutex → tokio::sync::Mutex (relay/service.rs)
- /auth/refresh 阻塞清理 → Scheduler 定期执行

Phase 4: 多环境配置
- config/saas-{development,production,test}.toml
- ZCLAW_ENV 环境选择 + ZCLAW_SAAS_CONFIG 精确覆盖
- scheduler 配置集成到 TOML
2026-03-29 19:21:48 +08:00

237 lines
7.3 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.

# loco-rs 架构模式研究 — zclaw-saas 重构参考
> 本文档记录 loco-rs (https://loco.rs) 的架构模式分析,评估其在 zclaw-saas 重构中的适用性。
> 创建时间: 2026-03-29
## 1. loco-rs 概述
- **定位**: "Rust on Rails" — 约定优于配置的全栈 Web 框架
- **技术栈**: Axum + SeaORM + PostgreSQL/SQLite
- **成熟度**: ~8K+ GitHub stars, 131+ contributors
- **官方站点**: https://loco.rs
## 2. 10 个可借鉴模式及评估
### 2.1 模式一: Worker trait后台任务抽象⭐ 高价值
**loco-rs 实现**:
- 基于 `sidekiq-rs``Worker` trait支持强类型参数
- 三种模式: `BackgroundQueue`Redis 队列)、`BackgroundAsync`(进程内 tokio`ForegroundBlocking`(同步)
- Worker 在 `Hooks::connect_workers()` 中注册
- 支持重试、延迟执行
**zclaw-saas 现状**:
- `main.rs` 中用 `tokio::spawn` + 手动 `interval` 循环
- 无重试、无命名、无观察性
**建议**: 采用框架无关的 Worker trait不依赖 Redis先用 `tokio::spawn` + channel未来可迁移到 Redis 队列。
```rust
// 建议实现
#[async_trait]
pub trait Worker: Send + Sync + 'static {
type Args: Serialize + DeserializeOwned + Send + Sync;
fn name(&self) -> &str;
async fn perform(&self, db: &PgPool, args: Self::Args) -> Result<(), SaasError>;
fn max_retries(&self) -> u32 { 3 }
}
```
---
### 2.2 模式二: 声明式 Scheduler ⭐ 高价值
**loco-rs 实现**:
- YAML 配置的 cron/interval 定时任务
- 支持 shell 命令或注册的 Task
- 按环境配置、按 tag 分组
**zclaw-saas 现状**:
- 硬编码 `tokio::spawn` + `Duration::from_secs(300)`
- 修改定时策略需要改代码重新编译
**建议**: 用 TOML 配置 scheduler与项目已有 TOML 基础一致),支持 interval 表达式。
```toml
[scheduler]
jobs = [
{ name = "cleanup_rate_limit", interval = "5m", task = "cleanup_rate_limit" },
{ name = "cleanup_devices", interval = "24h", task = "cleanup_devices" },
]
```
---
### 2.3 模式三: 类型化数据库模型 (FromRow) ⭐⭐ 最高价值
**loco-rs 实现**:
- SeaORM 实体自动生成(`sea-orm-cli generate entity`
- 强类型字段、关系、验证
**zclaw-saas 现状**:
- 原始元组解构 `(String, String, String, ...)`
- 无编译期字段检查,容易出错
**建议**: 不使用 SeaORM但用 `#[derive(sqlx::FromRow)]` 实现同样效果。
```rust
// Before (当前)
let (id, username, email, role, status) = sqlx::query_as::<_, (String, String, String, String, String)>(...)
// 5 个 String 参数,顺序错误编译器无法发现
// After (目标)
#[derive(sqlx::FromRow)]
pub struct AccountRow {
pub id: String,
pub username: String,
pub email: String,
pub role: String,
pub status: String,
pub created_at: DateTime<Utc>,
}
let row = sqlx::query_as::<_, AccountRow>("SELECT ...").fetch_one(db).await?;
```
---
### 2.4 模式四: SQL 迁移系统 ⭐ 高价值
**loco-rs 实现**:
- 迁移优先,先写 migration再从 DB 自动生成实体
- `sea-orm-cli migrate` 管理版本
**zclaw-saas 现状**:
- `db.rs` 内联 `SCHEMA_SQL` 常量,每次启动执行
- 无回滚能力DDL 混在应用代码中
- `SCHEMA_VERSION = 5` 手动追踪
**建议**: 使用 `sqlx-cli` 的迁移系统。
```
migrations/
├── 20260329000001_initial_schema.sql
├── 20260329000002_fix_timestamps.sql
└── 20260329000003_add_indexes.sql
```
---
### 2.5 模式五: CLI Task 系统 ⭐ 中等价值
**loco-rs 实现**:
- `Task` trait 用于手动执行运维操作
- `cargo loco task <NAME>` 命令行调用
- 支持参数传递
**zclaw-saas 现状**:
- 运维任务seed admin、schema 初始化)嵌入在 `db.rs``init_db()`
- 无法手动触发、无法传参
**建议**: 添加 Task trait + CLI 解析。
```rust
#[async_trait]
pub trait Task: Send + Sync {
fn name(&self) -> &str;
fn description(&self) -> &str;
async fn run(&self, state: &AppState, args: &HashMap<String, String>) -> SaasResult<()>;
}
```
---
### 2.6 模式六: 多环境配置 ⭐ 中等价值
**loco-rs 实现**:
- `development.yaml` / `production.yaml` / `test.yaml`
- 通过 `LOCO_ENV` 环境变量选择
- 支持 Tera 模板语法引用环境变量
**zclaw-saas 现状**:
- 单个 `saas-config.toml` 文件
- 通过 `ZCLAW_SAAS_CONFIG` 路径覆盖
**建议**: 采用环境分离配置。
```
config/
├── saas-development.toml
├── saas-production.toml
└── saas-test.toml
```
---
### 2.7 模式七: 可配置中间件栈 ⭐ 低价值
**loco-rs 实现**:
- YAML 配置 CORS、timeout、payload limit 等中间件参数
- Per-handler 和 per-route-group 的中间件层
**zclaw-saas 现状**:
- CORS origins、timeout 等硬编码在 `main.rs``build_router()`
**建议**: 当前优先级低,后续可将中间件参数移入 TOML 配置。
---
### 2.8 模式八: 集成测试辅助 ⭐ 中等价值
**loco-rs 实现**:
- `request::(|request, ctx| async { ... })` 风格的请求测试
- 自动启动测试 app + 测试数据库
- `assert_debug_snapshot!` 快照测试
**zclaw-saas 现状**:
- 基础的 `tests/account_test.rs`
**建议**: 添加测试辅助工具app 启动 + 请求发送 + fixture
---
### 2.9 ~~模式九: Fat Model~~ — 不建议采用
**loco-rs 实现**: 业务逻辑放在 `impl ActiveModel`Active Record 模式)
**原因**: 依赖 SeaORM 实体结构。zclaw-saas 使用 SQLxService Layer 模式更适合。
### 2.10 ~~模式十: SeaORM / YAML 配置~~ — 不建议采用
**原因**:
- SeaORM 引入 ORM 抽象层,与现有 SQLx 原始查询冲突
- YAML 在 Rust 生态中不如 TOML 类型安全
- loco-rs creator jondot 确认无增量集成路径,必须创建新项目迁移
## 3. zclaw-saas 与 loco-rs 架构对照
| 维度 | loco-rs | zclaw-saas (当前) | 建议 |
|------|---------|-------------------|------|
| Web 框架 | Axum | Axum | 保持不变 |
| 数据库层 | SeaORM (ORM) | SQLx (原始查询) | 保持 SQLx + FromRow |
| 后台任务 | sidekiq-rs (Redis) | tokio::spawn (手动) | **引入 Worker trait** |
| 定时任务 | YAML Scheduler | 硬编码 interval | **引入 TOML Scheduler** |
| 数据库模型 | 自动生成实体 | 元组解构 | **引入 FromRow** |
| 迁移系统 | sea-orm-cli | 内联 SQL | **引入 sqlx-cli** |
| 错误处理 | 统一 Error enum | SaasError (thiserror) | 已优秀,保持不变 |
| 配置系统 | YAML per-env | TOML 单文件 | **引入多环境配置** |
| CLI 任务 | Task trait | 嵌入 init 代码 | **引入 Task trait** |
| 测试 | 请求测试辅助 | 基础测试 | **引入测试辅助** |
## 4. 实施优先级
| 优先级 | 模式 | 价值 | 工作量 |
|--------|------|------|--------|
| 1 | FromRow 类型化模型 + 迁移系统 | 最高 | 中 |
| 2 | Worker trait 后台任务 | 高 | 低 |
| 3 | 声明式 Scheduler | 高 | 低 |
| 4 | CLI Task 系统 | 中 | 低 |
| 5 | 多环境配置 | 中 | 低 |
| 6 | 集成测试辅助 | 中 | 中 |
| 7 | 可配置中间件 | 低 | 低 |
## 5. 参考
- [loco.rs 官方文档](https://loco.rs/docs/the-app/)
- [loco-rs GitHub](https://github.com/loco-rs/loco)
- [Reddit: 如何从 Axum 迁移到 loco-rs](https://www.reddit.com/r/rust/comments/1g9hc1z/how_to_integratemigrate_to_locors_from_axum_app/)
- [Shuttle.dev: 介绍 Loco](https://www.shuttle.dev/blog/2023/12/20/loco-rust-rails)