在高性能后端开发领域,Axum 凭借其符合人体工程学的 API 和 Tokio 生态的强大支持,已经成为了 Rust 社区的事实标准。
然而,当我们试图将 Rust 引入到现有的企业级微服务架构(通常由 Java/Spring Cloud 主导)时,往往会面临“水土不服”的工程化难题:
- 配置管理困难:Rust 应用通常依赖环境变量或静态配置文件,如何像 Spring Cloud Config 一样实现中心化的动态配置更新?
- 服务发现缺失:如何让现有的 Java 服务通过 OpenFeign 无感调用 Rust 服务?
- 架构规范不统一:Rust 的自由度极高,如何约束项目结构,防止代码随着业务增长变成“意大利面条”?
为了解决这些痛点,我开源了 axum-template。
这是一个基于最新 Axum 0.8 + SeaORM 1.0 + Nacos 构建的生产级项目模板,旨在用 Rust 的方式复刻 Spring Boot 的开发体验。
核心定位:无缝融入 Spring Cloud 的高性能选择
这个模板不仅仅是一个 Web 框架的脚手架,它是一套面向微服务集成的工程化解决方案。它的主要目标是在现有的 Spring Cloud + Nacos 架构模式下,提供一个标准化的 Rust 后端接入方案,让团队在面对高性能计算或高并发场景时,多一种语言选择,而无需重构整个基础设施。它特别适合以下场景:
- Java 转 Rust 开发者:习惯了 Controller/Service/Repository 分层架构,希望在 Rust 中也能快速上手业务开发。
- 混合云/多语言架构:需要将高性能的 Rust 模块无缝嵌入现有的 Spring Cloud + Nacos 微服务生态中。
- 追求生产稳定性:开箱即用的动态配置、优雅停机、统一错误处理和日志追踪。
硬核技术栈
我们选用的都是 Rust 生态中最新、最经得起生产考验的库:
- Web 框架:
axum(v0.8) —— 极致性能,最新的路由 API 设计。 - 服务治理:
nacos-sdk(v0.5) —— 负责服务注册与发现,以及实时配置监听。 - ORM:
sea-orm(v1.0) —— 纯 Rust 的异步 ORM,提供编译期类型安全检查。 - 缓存:
bb8-redis—— 高性能、稳健的 Redis 连接池。 - HTTP 客户端:
reqwest—— 封装了类似 Feign 的服务间调用逻辑。 - 运行时:
tokio(v1) +tracing(结构化日志)。
架构亮点解析
1. 经典的分层架构 (SoC)
为了避免逻辑耦合,本项目采用了清晰的关注点分离(Separation of Concerns),让代码结构一目了然:
handlers/(Controller): 只负责 HTTP 请求的解析与校验、DTO 转换,然后调用 Service。这里还演示了如何使用Extension<Arc<CurrentUser>>进行类似于@PreAuthorize的声明式权限检查。services/: 纯粹的业务逻辑层,不关心 HTTP 细节,便于单元测试。repository/: 封装 SeaORM 的复杂查询逻辑,通过 Trait 提供数据访问接口。setup/: 将复杂的启动逻辑(Nacos 注册、数据库连接池初始化、Redis 连接)拆解为独立的模块,保持main.rs的整洁。
2. 真正的动态配置 (Dynamic Configuration)
很多 Rust 模板只支持启动时加载 .env,一旦配置变更就需要重启服务。
本模板通过 Nacos SDK 实现了配置热更新。当你在 Nacos 控制台修改 YAML 配置文件时:
- Rust 服务会实时监听到配置变更事件。
- 通过
RwLock安全地更新全局AppState中的配置结构体。 - 后续的请求将立即使用新的配置,无需重启服务。
3. 优雅停机 (Graceful Shutdown)
在 Kubernetes 环境中,Pod 销毁时如果处理不当,会导致流量黑洞(即请求发给了已经停止的服务)。
本模板监听了 SIGTERM 和 Ctrl+C 信号,在服务关闭前执行严格的清理流程:
- 主动注销:向 Nacos 发送注销请求,将实例从服务列表中移除。
- 等待请求:等待当前正在处理的 HTTP 请求完成(配合 Axum 的
GracefulShutdown)。 - 资源释放:断开数据库和 Redis 连接。
打通 Java 与 Rust 的任督二脉
这是本模板最大的特色——与 Spring Cloud 的无缝融合。
Java 调用 Rust
Rust 服务启动时会以 APP_NAME(例如 axum-template-service)注册到 Nacos。Java 端的 Spring Cloud OpenFeign 可以直接通过服务名调用 Rust 接口,就像调用另一个 Java 服务一样:
// Java 代码示例:像调用 Java 服务一样调用 Rust
@FeignClient(value = "axum-template-service")
public interface RemoteRustService {
@GetMapping("/hello")
ApiResponse<String> getHello();
}
Rust 调用 Java
我们也实现了“Rust 版的 Feign”。在 src/clients/ 目录下,封装了服务发现逻辑:
- 从 Nacos 查找目标服务(如
auth-service)的健康实例列表。 - 应用客户端负载均衡算法(如随机或轮询)。
- 通过
reqwest发起 HTTP 调用。
例如,在认证中间件中,Rust 会自动调用 Java 的 auth-service 校验 Token,实现了跨语言的鉴权闭环。
目录结构一览
axum-template/
├── src/
│ ├── config/ # 支持 .env 和 Nacos 动态配置
│ ├── setup/ # 启动引导 (Nacos, DB, Redis 初始化)
│ ├── clients/ # 微服务客户端 (Rust Feign 实现)
│ ├── handlers/ # HTTP 接口层 (Controllers)
│ ├── middleware/ # 认证 (Auth) 与日志中间件
│ ├── models/ # SeaORM 实体定义
│ ├── repository/ # 数据库访问层 (DAO)
│ ├── services/ # 核心业务逻辑层
│ ├── router.rs # 路由注册与组装
│ └── main.rs # 极简入口文件
快速开始
1. 环境准备
确保你本地或远程已经运行了 Nacos、MySQL 和 Redis。
2. 配置
复制项目根目录下的 .env 模板,配置 Nacos 地址:
NACOS_ADDR=127.0.0.1:8848
NACOS_NAMING_NAMESPACE=public
DATABASE_URL=mysql://user:pass@localhost:3306/db
并在 Nacos 中创建对应的 YAML 配置文件(DataId 需与 APP_NAME 匹配)。
3. 启动
cargo run
启动成功后,你可以在 Nacos 控制台的服务列表中看到名为 axum-template 的服务已上线。
结语
Rust 不应该是一座孤岛。
通过 axum-template,我希望展示 Rust 如何优雅地融入成熟的微服务生态体系。无论你是想用 Rust 重写性能敏感的核心模块,还是想体验一下高度模块化、工程化的 Rust 开发快感,都欢迎 Clone 试用!
如果你觉得这个项目对你有帮助,欢迎在 GitHub 上点个 Star ⭐️!