目录
1. 三大框架概览
| 特性 | Axum | Actix-web | Rocket |
|---|---|---|---|
| 维护方 | Tokio 团队(官方) | 社区(Actix) | 社区(Sergio Benitez) |
| 核心设计 | Tower Service 抽象 | Actor 模型 | 声明式宏 |
| 性能 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 学习曲线 | 中(需理解 Tower) | 低 | 低 |
| 中间件 | Tower layer | 自定义 guard/middleware | Fairing + Guard |
| 稳定版状态 | ✅ 1.0 | ✅ 4.x | ✅ 0.5 |
2. Axum:Tower 生态现代框架
Axum 基于 hyper HTTP 服务器和 tower 中间件抽象,是 Tokio 官方推荐的 Web 框架。
2.1 Hello World
use axum::{routing::get, Router};
use std::net::SocketAddr;
#[tokio::main]
async fn main() {
let app = Router::new().route("/", get(|| async { "Hello, Axum!" }));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
axum::serve(listener, app).await.unwrap();
}
2.2 路由与提取器
use axum::{
routing::{get, post},
extract::{Path, Query, Json, State},
Router,
};
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
struct Pagination {
page: Option<u32>,
per_page: Option<u32>,
}
#[derive(Serialize)]
struct User {
id: u64,
name: String,
}
async fn list_users(
Query(pagination): Query<Pagination>,
) -> Json<Vec<User>> {
let page = pagination.page.unwrap_or(1);
Json(vec![User { id: 1, name: "Alice".to_string() }])
}
async fn get_user(Path(id): Path<u64>) -> Json<User> {
Json(User { id, name: "Bob".to_string() })
}
async fn create_user(Json(user): Json<CreateUserReq>) -> Json<User> {
Json(User { id: 42, name: user.name })
}
let app = Router::new()
.route("/users", get(list_users).post(create_user))
.route("/users/:id", get(get_user));
2.3 状态管理与依赖注入
use std::sync::Arc;
use tokio::sync::RwLock;
#[derive(Clone)]
struct AppState {
db: Arc<RwLock<Vec<User>>>,
config: Arc<Config>,
}
let state = AppState {
db: Arc::new(RwLock::new(vec![])),
config: Arc::new(Config::default()),
};
let app = Router::new()
.route("/users", get(list_users))
.with_state(state);
async fn list_users(State(state): State<AppState>) -> Json<Vec<User>> {
let users = state.db.read().await.clone();
Json(users)
}
2.4 中间件(Tower Layer)
use tower_http::{trace::TraceLayer, cors::CorsLayer, compression::CompressionLayer};
let app = Router::new()
.route("/", get(handler))
.layer(CorsLayer::permissive())
.layer(CompressionLayer::new())
.layer(TraceLayer::new_for_http());
自定义中间件:
async fn auth_middleware<B>(
req: Request<B>,
next: Next<B>,
) -> Result<Response, StatusCode> {
let auth = req.headers()
.get("authorization")
.and_then(|h| h.to_str().ok());
match auth {
Some(token) if valid_token(token) => Ok(next.run(req).await),
_ => Err(StatusCode::UNAUTHORIZED),
}
}
let app = Router::new()
.route("/protected", get(secret_handler))
.layer(middleware::from_fn(auth_middleware));
2.5 错误处理
use axum::{response::IntoResponse, http::StatusCode};
use thiserror::Error;
#[derive(Error, Debug)]
enum AppError {
#[error("database error")]
Database(#[from] sqlx::Error),
#[error("not found")]
NotFound,
#[error("validation error: {0}")]
Validation(String),
}
impl IntoResponse for AppError {
fn into_response(self) -> Response {
let (status, message) = match self {
AppError::Database(_) => (StatusCode::INTERNAL_SERVER_ERROR, "Internal error"),
AppError::NotFound => (StatusCode::NOT_FOUND, "Not found"),
AppError::Validation(msg) => (StatusCode::BAD_REQUEST, msg.as_str()),
};
(status, Json(json!({ "error": message }))).into_response()
}
}
3. Actix-web:Actor 模型高性能
Actix-web 基于 Actix Actor 框架,以极致性能和丰富功能著称。
3.1 Hello World
use actix_web::{get, App, HttpServer, Responder};
#[get("/")]
async fn hello() -> impl Responder {
"Hello, Actix!"
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().service(hello))
.bind("127.0.0.1:3000")?
.run()
.await
}
3.2 路由与数据提取
use actix_web::{web, HttpResponse, Result};
use serde::Deserialize;
#[derive(Deserialize)]
struct Info {
user_id: u64,
friend: String,
}
#[get("/users/{user_id}/{friend}")]
async fn user_info(info: web::Path<Info>) -> Result<HttpResponse> {
Ok(HttpResponse::Ok().json(json!({
"user_id": info.user_id,
"friend": info.friend,
})))
}
// 应用程序状态
struct AppState {
app_name: String,
}
#[get("/app_name")]
async fn app_name(data: web::Data<AppState>) -> String {
data.app_name.clone()
}
HttpServer::new(|| {
App::new()
.app_data(web::Data::new(AppState { app_name: "MyApp".to_string() }))
.service(user_info)
.service(app_name)
})
3.3 中间件
use actix_web::middleware::{Logger, Compress, DefaultHeaders};
HttpServer::new(|| {
App::new()
.wrap(Logger::default()) // 请求日志
.wrap(Compress::default()) // 响应压缩
.wrap(DefaultHeaders::new().add(("X-Version", "1.0")))
.service(hello)
})
3.4 多线程工作器
HttpServer::new(|| { ... })
.workers(4) // 4 个工作线程
.bind("127.0.0.1:3000")?
.run()
4. Rocket:声明式语法先行者
Rocket 使用 Rust 的声明宏实现高度简洁的代码。
4.1 Hello World
#[macro_use] extern crate rocket;
#[get("/")]
fn hello() -> &'static str {
"Hello, Rocket!"
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![hello])
}
4.2 路由与守卫
use rocket::serde::{Serialize, json::Json};
use rocket::request::{FromRequest, Outcome, Request};
#[derive(Serialize)]
struct User { id: u64, name: String }
#[get("/users/<id>")]
fn get_user(id: u64) -> Option<Json<User>> {
Some(Json(User { id, name: "Alice".to_string() }))
}
// 自定义守卫:API Key 验证
struct ApiKey<'r>(&'r str);
#[rocket::async_trait]
impl<'r> FromRequest<'r> for ApiKey<'r> {
type Error = ();
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
match req.headers().get_one("x-api-key") {
Some(key) => Outcome::Success(ApiKey(key)),
None => Outcome::Forward(Status::Unauthorized),
}
}
}
#[get("/admin")]
fn admin_panel(key: ApiKey<'_>) -> String {
format!("Admin access with key: {}", key.0)
}
4.3 数据验证
use rocket::serde::Deserialize;
use rocket_validation::{Validate, Validated};
#[derive(Deserialize, Validate)]
struct CreateUser {
#[validate(length(min = 1, max = 50))]
name: String,
#[validate(email)]
email: String,
}
#[post("/users", data = "<user>")]
fn create_user(user: Validated<Json<CreateUser>>) -> Json<User> {
Json(User { id: 1, name: user.name.clone() })
}
5. 框架选型指南
| 场景 | 推荐框架 | 理由 |
|---|---|---|
| 微服务/API 网关 | Axum | Tokio 官方支持,Tower 生态丰富,hyper 底层 |
| 极高吞吐量服务 | Actix-web | TechEmpower 基准测试常年前三 |
| 快速原型开发 | Rocket | 声明式语法最简洁,文档优秀 |
| 需要 WebSocket | Actix-web | 内置完善的 WebSocket 支持 |
| 与 gRPC 混部 | Axum | tonic (gRPC) 同为 Tower 生态 |
| 团队 Rust 新手多 | Rocket | 编译器错误信息最友好 |
6. 认证与授权实现
6.1 JWT 认证中间件(Axum)
use jsonwebtoken::{decode, DecodingKey, Validation, Algorithm};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
sub: String,
exp: usize,
roles: Vec<String>,
}
async fn jwt_middleware<B>(
mut req: Request<B>,
next: Next<B>,
) -> Result<Response, StatusCode> {
let token = req.headers()
.get("authorization")
.and_then(|h| h.to_str().ok())
.and_then(|h| h.strip_prefix("Bearer "));
let claims = token
.and_then(|t| decode::<Claims>(
t,
&DecodingKey::from_secret("secret".as_ref()),
&Validation::new(Algorithm::HS256),
).ok())
.map(|d| d.claims)
.ok_or(StatusCode::UNAUTHORIZED)?;
req.extensions_mut().insert(claims);
Ok(next.run(req).await)
}
6.2 OAuth2 集成
use oauth2::{AuthorizationCode, TokenResponse};
async fn oauth_callback(
Query(params): Query<OAuthCallback>,
) -> Result<Redirect, AppError> {
let token = oauth_client
.exchange_code(AuthorizationCode::new(params.code))
.request_async(async_http_client)
.await?;
let user = fetch_user_info(token.access_token().secret()).await?;
// 创建/更新用户,颁发 JWT
Ok(Redirect::to("/dashboard"))
}
7. 数据库集成:SQLx 与 ORM
7.1 SQLx(编译时检查 SQL)
use sqlx::{PgPool, query_as};
#[derive(sqlx::FromRow)]
struct User {
id: i64,
name: String,
email: String,
}
async fn get_user(pool: &PgPool, id: i64) -> Result<User, sqlx::Error> {
query_as::<_, User>("SELECT id, name, email FROM users WHERE id = $1")
.bind(id)
.fetch_one(pool)
.await
}
// 连接池初始化
let pool = PgPool::connect("postgres://user:pass@localhost/db").await?;
7.2 Sea-ORM(异步 ORM)
use sea_orm::{entity::*, query::*, Database};
// 自动生成 entity
db_user::Entity::find()
.filter(db_user::Column::Name.contains("Alice"))
.order_by_asc(db_user::Column::Id)
.all(&db)
.await?;
7.3 Diesel(同步 ORM + spawn_blocking)
use diesel::prelude::*;
let users = web::block(move || {
let mut conn = pool.get()?;
users::table.filter(users::name.eq("Alice")).load::<User>(&mut conn)
})
.await??;
| 方案 | 类型安全 | 编译时检查 | 异步原生 | 成熟度 |
|---|---|---|---|---|
| SQLx | ✅ | ✅ SQL | ✅ | ⭐⭐⭐⭐⭐ |
| Sea-ORM | ✅ | ✅ Schema | ✅ | ⭐⭐⭐⭐ |
| Diesel | ✅ | ✅ Schema | ❌(需 blocking) | ⭐⭐⭐⭐⭐ |
8. 生产部署与性能优化
8.1 健康检查与指标
use axum::{Router, routing::get};
let app = Router::new()
.route("/health", get(|| async { "OK" }))
.route("/metrics", get(metrics_handler));
8.2 优雅关闭
async fn graceful_shutdown(handle: axum::ServerHandle) {
let ctrl_c = tokio::signal::ctrl_c();
let terminate = std::future::pending();
tokio::select! {
_ = ctrl_c => {},
_ = terminate => {},
}
println!("Shutdown signal received");
handle.graceful_shutdown(Some(Duration::from_secs(30)));
}
8.3 Docker 多阶段构建
FROM rust:1.80-slim AS builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM gcr.io/distroless/cc-debian12
COPY --from=builder /app/target/release/myapp /usr/local/bin/
EXPOSE 3000
CMD ["myapp"]
8.4 性能基准
# TechEmpower 单查询基准(每秒请求数)
# Actix-web: ~700K req/s
# Axum: ~650K req/s
# Rocket: ~400K req/s
# 对比 Go Gin: ~500K req/s
# 对比 Node.js Express: ~50K req/s
# 使用 wrk 自测
wrk -t12 -c400 -d30s http://localhost:3000/
Rust Web 框架在 HTTP 吞吐量上已达到甚至超越 Go 和 Java 的水平,同时提供编译期内存安全保证。Axum 的 Tower 生态、Actix-web 的极致性能、Rocket 的开发体验,三者覆盖不同场景,选型建议从团队熟悉度和具体需求出发。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。
「rust」更多文章
Rust 错误处理与测试:thiserror、mockall 与属性测试
Rust 错误处理最佳实践:Result/Option 组合子、thiserror 与 anyhow 选型、panic 边界控制、单元/集成/文档测试、mockall 模拟、property-based testing 与代码覆盖率。
Rust 系统编程与性能优化:零拷贝、内存剖析与编译调优
Rust 系统编程深度实践:操作系统原语、零拷贝 I/O、mmap 内存映射、性能剖析(cargo flamegraph)、编译器优化(LTO/PGO)、Benchmark 与内存分析,以及 no_std 嵌入式场景。
Rust 桌面端与 WASM:Tauri、WebAssembly 与嵌入式开发
Rust 跨平台开发全景:Tauri 替代 Electron 的轻量级架构、WASM 编译(wasm-bindgen/wasm-pack)、WASI 运行时、嵌入式 Rust(no_std/embedded-hal),以及跨平台发布策略。