《Rust 实战指南》实战项目 B:云原生微服务——构建高并发短链接系统

Rust构建高并发短链接系统

项目导读

作为 Java 开发者,你一定熟悉 Spring Boot 的“约定大于配置”,但也忍受过启动时漫长的 Bean 扫描,以及空载时 300MB 起步的内存占用。
作为 Python 开发者,你享受 FastAPI 的开发速度,但当 QPS 上来时,你不得不面对 GIL 锁带来的吞吐量瓶颈,甚至要把业务逻辑迁移到 Go。

Rust 的 Web 生态已经成熟。特别是 Axum(基于 Tokio)和 Sqlx(异步数据库驱动)的组合,被称为现代后端开发的“黄金搭档”。

在这个实战项目中,我们将构建一个短链接服务(URL Shortener)。这不仅仅是一个 Demo,它包含了商业项目必备的要素:数据库连接池、依赖注入(状态管理)、统一错误处理、结构化日志以及 Docker 极小镜像构建。

准备好见证奇迹了吗?我们将把一个完整的 Web 服务打包进 20MB 的 Docker 镜像中,且运行时内存仅需 15MB


🎯 本项目学习目标

  1. 框架选型:掌握 Axum 框架的核心概念(路由、提取器、中间件)。
  2. 数据持久化:使用 Sqlx 操作 PostgreSQL,体验编译期 SQL 检查的黑科技。
  3. 架构设计:学习如何在 Rust 中实现类似 Spring 的“依赖注入”(通过 AppState)。
  4. 错误处理:构建全局统一的错误处理机制(IntoResponse),告别混乱的 try-catch
  5. 云原生交付:编写多阶段构建的 Dockerfile,产出 Distroless 级别的超小镜像。
  6. 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

撸码猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值