项目导读
作为 Java 开发者,你一定熟悉 Spring Boot 的“约定大于配置”,但也忍受过启动时漫长的 Bean 扫描,以及空载时 300MB 起步的内存占用。
作为 Python 开发者,你享受 FastAPI 的开发速度,但当 QPS 上来时,你不得不面对 GIL 锁带来的吞吐量瓶颈,甚至要把业务逻辑迁移到 Go。Rust 的 Web 生态已经成熟。特别是 Axum(基于 Tokio)和 Sqlx(异步数据库驱动)的组合,被称为现代后端开发的“黄金搭档”。
在这个实战项目中,我们将构建一个短链接服务(URL Shortener)。这不仅仅是一个 Demo,它包含了商业项目必备的要素:数据库连接池、依赖注入(状态管理)、统一错误处理、结构化日志以及 Docker 极小镜像构建。
准备好见证奇迹了吗?我们将把一个完整的 Web 服务打包进 20MB 的 Docker 镜像中,且运行时内存仅需 15MB。
🎯 本项目学习目标
- 框架选型:掌握 Axum 框架的核心概念(路由、提取器、中间件)。
- 数据持久化:使用 Sqlx 操作 PostgreSQL,体验编译期 SQL 检查的黑科技。
- 架构设计:学习如何在 Rust 中实现类似 Spring 的“依赖注入”(通过
AppState)。 - 错误处理:构建全局统一的错误处理机制(
IntoResponse),告别混乱的try-catch。 - 云原生交付:编写多阶段构建的
Dockerfile,产出 Distroless 级别的超小镜像。 - AI 辅助:利用 AI 生成 SQL 迁移脚本和集成测试代码。
B.1 项目初始化与架构规划
不同于 Python 的随意文件结构,Rust 商业项目讲究模块化。
B.1.1 创建项目与依赖
cargo new short_link_service
cd short_link_service
编辑 Cargo.toml,我们要引入“全家桶”:
[package]
name = "short_link_service"
version = "0.1.0"
edition = "2021"
[dependencies]
# Web 框架,Tokio 官方出品,人体工程学极佳
axum = "0.7"
# 异步运行时
tokio = { version = "1.0", features = ["full"] }
# 序列化
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
# 数据库 ORM/Mapper
sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres", "uuid", "chrono"] }
# 环境变量管理
dotenvy = "0.15"
# 结构化日志与追踪
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
# 唯一 ID 生成
nanoid = "0.4.0"
# 错误处理
thiserror = "1.0"
B.1.2 目录结构设计
我们采用经典的分层架构,但比 Java 更轻量:
src/
├── main.rs # 程序入口,组装路由和状态
├── config.rs # 配置加载
├── db.rs # 数据库连接池初始化
├── handlers.rs # 控制器(Controller)逻辑
├── models.rs # 数据模型(DTO/POJO)
└── errors.rs # 全局错误定义
B.2 数据库先行:Sqlx 的魔法
Java 的 Hibernate/MyBatis 需要 xml 配置或大量的注解,且 SQL 写错了要等到运行时才知道。Sqlx 颠覆了这一点:它在编译时连接数据库检查 SQL 语法。
B.2.1 启动 PostgreSQL
为了方便,我们使用 Docker 启动数据库。
docker run --name pg -e POSTGRES_PASSWORD=password -p 5432:5432 -d postgres:15-alpine
在项目根目录创建 .env 文件:
DATABASE_URL=postgres://postgres:password@localhost:5432/postgres
RUST_LOG=debug
B.2.2 AI 辅助生成 Schema
我们需要一张表存短链接。
Prompt 建议:
“我正在用 Rust 和 Postgres 做短链接系统。请帮我写一个
CREATE TABLE的 SQL 语句。字段包括:id (char 6, 主键), original_url (text, 非空), created_at (timestamp), visits (int)。请考虑性能索引。”
AI 会给出 SQL。我们需要安装 sqlx-cli 来管理迁移:
cargo install sqlx-cli
sqlx database create
sqlx migrate add init_schema
将 AI 生成的 SQL 填入 migrations/xxxx_init_schema.up.sql:
CREATE TABLE IF NOT EXISTS links (
id CHAR(6) PRIMARY KEY,
original_url TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
visits INT NOT NULL DEFAULT 0
);
执行迁移:sqlx migrate run。
B.3 核心代码实现
B.3.1 定义数据模型 (src/models.rs)
use serde::{
Deserialize, Serialize};
use sqlx::FromRow;
// 对应数据库表结构
#[derive(Debug, FromRow, Serialize)]
pub struct Link {
pub id: String,
pub original_url: String,
pub created_at: chrono::DateTime<chrono::Utc>,
pub visits: i32,
}
// 接收前端创建请求的 DTO
#[derive(Debug, Deserialize)]
pub struct CreateLinkReq {
pub url: String,
}
// 返回给前端的 DTO
Rust构建高并发短链接系统

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



