架构
StackRivet 是模块化单体:一个可部署的 Spring Boot 应用,拆成边界清晰、且被强制保障的若干模块。它不是微服务网格,也不是松散的后台模板。
目的是让小团队(或 AI 编码工具)快速交付,同时不放弃那些让真实企业项目可维护的边界。
flowchart LR
Web["Vue 3 管理端"]
CLI["CLI"]
API["REST / OpenAPI"]
subgraph Backend["后端模块"]
Sec["认证与 RBAC"]
Sys["系统管理"]
Asset["Asset Service"]
Gen["代码生成器"]
Task["异步任务"]
end
DB[("MySQL / PostgreSQL")]
Store["S3 / OSS / 本地"]
Redis[("Redis")]
Web --> API
CLI --> API
API --> Sec
API --> Sys
API --> Asset
API --> Gen
API --> Task
Sec --> DB
Sys --> DB
Gen --> DB
Task --> DB
Asset --> Store
API -.-> Redis
为什么是模块化单体
Section titled “为什么是模块化单体”| 目标 | 架构如何支撑 |
|---|---|
| 10 分钟启动项目 | 单进程、一条 docker compose、一条 mvn spring-boot:run |
| 30 分钟生成可运行模块 | 代码生成器同步产出后端、前端、菜单、权限、OpenAPI 和测试 |
| 让 AI 待在边界内 | 模块边界、分层与测试规则都写明、且机器可读 |
| 二开后仍可升级 | 模块 manifest、Flyway 迁移、模板版本记录改了什么 |
| 日后演进而非重写 | 清晰的模块缝隙意味着真正需要时再抽出服务——而不是第一天就拆 |
你现在拿到的是单代码库的开发速度,同时留好了清晰的拆分缝隙:等真的有需要时,再把某块拆成独立服务。
后端是 16 个 Maven 模块。完整清单与职责见项目结构;从架构上看,真正重要的是它们之间的依赖方向。
这些规则不是建议——它们由 stackrivet-app 中的 ArchUnit 测试强制保障,违反即构建失败:
stackrivet-common不依赖任何业务模块。 它只放共享原语:R<T>、PageR<T>、TraceIdHolder、BusinessException、基础实体。stackrivet-security不依赖stackrivet-system或其sr_sys_*表。 认证所需的用户/角色数据,通过common中定义的SystemUserDirectorySPI 获取。安全模块与系统模块的存储解耦。stackrivet-asset从不引用业务表。 它只通过bizType、refId和一个权限 SPI 关联你的数据——这样文件层不会被卷进每个功能的表结构。stackrivet-generator不直接写核心源码。 所有产物都经由模板和模块 manifest 输出,这正是生成代码可评审、可升级的关键。- 示例模块永不成为核心模块的依赖。
stackrivet-demo消费公开 API,不能反向污染核心。
结果是一张无环依赖图:security、system、audit、asset、generator 都是独立、可替换的模块。
每个业务模块遵循同样的四层,请求只能单向流动:
Controller → Application / Service → Domain → Infrastructure / Mapper| 层 | 职责 | 禁止 |
|---|---|---|
| Controller | 参数校验、权限注解、OpenAPI 注解、响应包装 | 写业务规则;直接调 Mapper |
| Application / Service | 用例编排、事务、权限上下文、审计事件 | 把数据库实体返回给前端 |
| Domain | 领域规则、状态流转、值对象 | 依赖 Web 或持久化框架 |
| Infrastructure / Mapper | SQL、持久化、外部适配器 | 绕过 Service 暴露给 Controller |
| DTO / VO | 入参与出参模型 | 跨边界复用 Entity |
实体永不越过持久化边界——跨边界用 DTO 和 VO。代码生成器同样受此约束:它不会产出“Controller 直接调 Mapper”的捷径。
架构默认拒绝:
- 未认证返回 401;未授权返回 403。
- 每个受保护端点都声明自己的权限;生成的模块带着权限注解发布,而不是不带。
- 五层权限覆盖整个面:菜单(导航)、按钮(UI 操作)、API(服务端入口)、数据(查询范围)、资产(私有文件访问)。
完整模型见安全与 RBAC。
- 1.0 同时支持 MySQL 8.4 LTS 和 PostgreSQL 18.4。
- 所有结构变更都走 Flyway——不允许手改生产库后再补文档。
- 表名用
sr_前缀,避免 StackRivet 进入客户数据库后冲突。 - 核心表带
id、created_at、updated_at;可审计表加created_by/updated_by;多租户相关表带tenant_id;软删除表带deleted/deleted_at。
每个请求都带 traceId,并在统一异常响应中返回,因此 UI 上的错误能追到服务端日志。Actuator、Micrometer 和可选的 OpenTelemetry profile 都内置,stackrivet doctor 可诊断常见环境问题(JDK、Node、Docker、数据库、对象存储、端口占用)。
同一个应用从笔记本到 HA 集群都能跑:
| 形态 | 拓扑 |
|---|---|
| 本地开发 | Vite dev server + Spring Boot + Docker MySQL/PostgreSQL + MinIO |
| 小团队生产 | Nginx → 静态管理端 + Spring Boot 应用 → 托管数据库 + S3/OSS |
| 企业 | 负载均衡 → 多个应用节点 → HA 数据库 + 企业对象存储 + OIDC/SAML/LDAP |
由于应用以无状态为目标(上传直传对象存储、重任务走异步、列表分页),横向扩展就是在负载均衡后加节点——而不是重做架构。