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
7.3 KiB
7.3 KiB
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的Workertrait,支持强类型参数 - 三种模式:
BackgroundQueue(Redis 队列)、BackgroundAsync(进程内 tokio)、ForegroundBlocking(同步) - Worker 在
Hooks::connect_workers()中注册 - 支持重试、延迟执行
zclaw-saas 现状:
main.rs中用tokio::spawn+ 手动interval循环- 无重试、无命名、无观察性
建议: 采用框架无关的 Worker trait,不依赖 Redis(先用 tokio::spawn + channel),未来可迁移到 Redis 队列。
// 建议实现
#[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 表达式。
[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)] 实现同样效果。
// 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 实现:
Tasktrait 用于手动执行运维操作cargo loco task <NAME>命令行调用- 支持参数传递
zclaw-saas 现状:
- 运维任务(seed admin、schema 初始化)嵌入在
db.rs的init_db()中 - 无法手动触发、无法传参
建议: 添加 Task trait + CLI 解析。
#[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 使用 SQLx,Service 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 | 可配置中间件 | 低 | 低 |