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

作者:撸码猿日期:2025/12/1

项目导读

作为 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 创建项目与依赖

1cargo new short_link_service
2cd short_link_service
3

编辑 Cargo.toml,我们要引入“全家桶”:

1[package]
2name = "short_link_service"
3version = "0.1.0"
4edition = "2021"
5
6[dependencies]
7# Web 框架,Tokio 官方出品,人体工程学极佳
8axum = "0.7"
9# 异步运行时
10tokio = { version = "1.0", features = ["full"] }
11# 序列化
12serde = { version = "1.0", features = ["derive"] }
13serde_json = "1.0"
14# 数据库 ORM/Mapper
15sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres", "uuid", "chrono"] }
16# 环境变量管理
17dotenvy = "0.15"
18# 结构化日志与追踪
19tracing = "0.1"
20tracing-subscriber = { version = "0.3", features = ["env-filter"] }
21# 唯一 ID 生成
22nanoid = "0.4.0"
23# 错误处理
24thiserror = "1.0"
25

B.1.2 目录结构设计

我们采用经典的分层架构,但比 Java 更轻量:

1src/
2├── main.rs          # 程序入口,组装路由和状态
3├── config.rs        # 配置加载
4├── db.rs            # 数据库连接池初始化
5├── handlers.rs      # 控制器(Controller)逻辑
6├── models.rs        # 数据模型(DTO/POJO)
7└── errors.rs        # 全局错误定义
8

B.2 数据库先行:Sqlx 的魔法

Java 的 Hibernate/MyBatis 需要 xml 配置或大量的注解,且 SQL 写错了要等到运行时才知道。Sqlx 颠覆了这一点:它在编译时连接数据库检查 SQL 语法。

B.2.1 启动 PostgreSQL

为了方便,我们使用 Docker 启动数据库。

1docker run --name pg -e POSTGRES_PASSWORD=password -p 5432:5432 -d postgres:15-alpine
2

在项目根目录创建 .env 文件:

1DATABASE_URL=postgres://postgres:password@localhost:5432/postgres
2RUST_LOG=debug
3

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 来管理迁移:

1cargo install sqlx-cli
2sqlx database create
3sqlx migrate add init_schema
4

将 AI 生成的 SQL 填入 migrations/xxxx_init_schema.up.sql

1CREATE TABLE IF NOT EXISTS links (
2    id CHAR(6) PRIMARY KEY,
3    original_url TEXT NOT NULL,
4    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
5    visits INT NOT NULL DEFAULT 0
6);
7

执行迁移:sqlx migrate run


B.3 核心代码实现

B.3.1 定义数据模型 (src/models.rs)

1use serde::{
2   
3   Deserialize, Serialize};
4use sqlx::FromRow;
5
6// 对应数据库表结构
7#[derive(Debug, FromRow, Serialize)]
8pub struct Link {
9   
10   
11    pub id: String,
12    pub original_url: String,
13    pub created_at: chrono::DateTime<chrono::Utc>,
14    pub visits: i32,
15}
16
17// 接收前端创建请求的 DTO
18#[derive(Debug, Deserialize)]
19pub struct CreateLinkReq {
20   
21   
22    pub url: String,
23}
24
25// 返回给前端的 DTO
26

《Rust 实战指南》实战项目 B:云原生微服务——构建高并发短链接系统》 是转载文章,点击查看原文


相关推荐


从零开始:用Python和Gemini 3四步搭建你自己的AI Agent
deephub2025/11/29

很多人第一次看到 AI Agent 自己编辑文件、跑代码、修 bug,还能一直运行下去的时候,都觉得挺神奇。其实远没有想象中那么复杂。这里没什么秘密算法,也没有什么"智能体大脑"这种玄学概念。 AI Agent核心就三件事:循环 + LLM + 工具函数。 如果你会写个 while True 循环?那基本就算成功一半了。 这篇文章会完整展示怎么用 Gemini 3 搭一个真正能用的 Agent:从最基础的 API 调用,到一个能读写文件、理解需求的命令行助手。 Agent 到底是


提升 EdgeWorker 可观测性:使用 DataStream 设置日志功能
AKAMAI2025/11/26

关于作者:AJ Johnson 是 Akamai Technologies 的高级产品经理,专注于平台即服务(PaaS),并领导旨在扩展和优化公司云平台能力的战略计划。 如您所在的企业也在考虑采购云服务或进行云迁移, 点击链接了解Akamai Linode解决方案,现在申请试用可得高达500美元专属额度 询问任何开发者,他们都会告诉您,良好且及时的应用遥测对于构建、维护和优化应用程序至关重要。没有适当的反馈,开发人员就如同在黑暗中摸索,难以识别逻辑错误、合规性问题以及优化空间。应用日志记录


Python异步爬虫实战:从基础请求到高效数据抓取的全流程解析与优化技巧
2501_941801762025/11/24

在互联网技术飞速发展的今天,数据获取和处理成为了各类应用的核心能力。Python 以其简洁、高效的特性,成为了网络爬虫与数据抓取领域的首选语言。今天,我们将从基础请求开始,逐步深入 Python 异步爬虫的实践方法,并结合优化技巧分享一些实战经验。 一、网络请求基础 网络爬虫的核心是 HTTP 请求。Python 内置的 requests 库为同步请求提供了非常友好的接口,使用起来极为方便。例如,简单的网页抓取可以通过以下方式实现: import requests url = 'ht


进程、线程、协程三者的区别和联系
爱学习的小道长2025/11/23

1. 核心概念对比 特性维度进程 (Process)线程 (Thread)协程 (Coroutine)基本定义资源分配的基本单位,拥有独立的地址空间CPU调度的基本单位,共享进程的资源用户态的轻量级线程,在单线程内通过协作进行任务切换隔离性强,一个进程崩溃通常不会影响其他进程弱,一个线程崩溃可能导致整个进程退出,影响同进程所有线程。无,所有协程在同一线程内运行。开销大,创建、销毁和上下文切换(涉及页表、寄存器等)成本高。中等,创建和切换开销比进程小,但仍需内核介入。极小,切换由程序控制,无需内


Redis(136)Redis的客户端缓存是如何实现的?
Victor3562025/11/21

Redis 的客户端缓存(Client-Side Caching)是一项重要特性,允许客户端在本地缓存 Redis 数据,从而减少与 Redis 服务器的通信频率,提高应用的响应速度和可扩展性。Redis 客户端缓存的实现主要依赖于以下几个核心组件和机制: 订阅机制:客户端通过订阅特定的键空间事件,获取键的变更通知。 通知机制:Redis 服务器在键发生变更时,通过发布/订阅(Pub/Sub)机制将变更通知推送给客户端。 缓存一致性:确保客户端缓存与 Redis 服务器的数据一致性。 核心概


【AI省流快讯】Cloudflare 炸了 / Gemini 3 来了 / Antigravity 独家实测 (附:无法登录解法)
coder_pig2025/11/19

1. Cloudflare 挂了 🤡 昨晚陆续刷到 "CF挂了" 的消息,没太在意,直到无法打开" 盗版漫画" 站点,我才意识到问题的严重性: 🤣 原因众说纷纭,刷到这哥们的 "梗图",差点把我笑岔气: 😃 还有人猜测可能是 Google 发布的 "哈基米 3" (Gemini) 发起的攻击: 时间线: 【19:30】用户开始报告网站无法访问,出现10xx、52x、50x系列错误;Cloudflare Dashboard无法访问;部分Cloudflare域名解析中断。 【19:4


Excel处理控件Aspose.Cells教程:使用Python从Excel工作表中删除数据透视表
IT开发者笔记2025/11/18

在使用 Excel 处理数据时,数据透视表通过汇总大型数据集,简化了分析过程。但随着分析的深入,您可能需要删除旧的数据透视表,以保持工作表的整洁或为新的分析结果做好准备。您可以快速删除任何数据透视表,无需手动查找,也不会留下任何失效的引用。本教程将逐步介绍如何借助Aspose.Cells使用Python从Excel 工作表中删除数据透视表。 Aspose.Cells官方试用版免费下载 本篇教程适合: 使用Excel高级用户自动生成每月演示文稿每周一都要重建仪表盘的数据分析师宁愿写五行代码也


用 TRAE SOLO 高效开发的 12 个小技巧
TRAE_ai2025/11/17

本文作者:云舒,TRAE 产品运营 用 SOLO 高效开发的 12 个技巧,从入门到精通,带你玩转 SOLO。 第一部分:入门篇 技巧 1:根据项目需求选择合适的内置智能体 TRAE SOLO 内置了两个核心智能体:SOLO Coder和 SOLO Builder,它们分别适用于不同的开发场景,明确场景后选择合适的智能体,能显著提升推进效率与结果质量。 如果你想处理基于现有代码库的迭代、重构和 Bug 修复等复杂任务,SOLO Coder 是最佳的选择,它具备优秀的项目理解和上下文管理能力


linux之ubuntu qt界面开发开发点菜系统
RouDragon2025/11/16

首先这篇博客主要讲解的是如何设计一个基于qt开发的点菜系统,这方面有很多内容会引用他人的文章需要继续学习他人的文章才会明白此文章是在讲解啥。 自制点菜系统视频链接 整体设计思路     这张图其实很详细的介绍了点菜系统需要的技术,在开发板方面,也就是服务器端,首先屏幕显示也是基于qt开发,所有你的ubuntu qt开发的时候就得设置好其编译器和环境基于开发板的,同时你还需要另一套环境进行直接在开发板上测试不需要反反复复的在开发板上重装。屏幕显示部分还需要首先设置一个登陆界面当客户


进入职场第五课——突破和跃升
Mapbarfront2025/11/14

观察、融入、立足、产出,度过这4个阶段之后,你已经稳稳地,成为团队里的主力输出了,接下来,如果你想从团队中的好员工,跃升为老板眼中的关键人物,从业务骨干到真正的团队核心,必须要做的下一步就是突破,易经乾卦中的或跃在渊,说的就是这个意思。 或是或许,代表着不确定性,跃是跳跃,代表着勇敢一搏,在渊是指在深渊里,代表着突破前在深渊里的等待,这个阶段,是你在积蓄了足够的力量之后,遇到合适的机会纵身一跃的时刻,这是审慎的冒险,也是耐心等待之后的水到渠成,想要完成这次关键的进阶,以下这5个动作,你要步步为营

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2025 聚合阅读