定位
Actix Web 长期占据 Rust Web 框架性能榜前列。历史上有过 Actor 模型的设计,现在是常规异步框架,但保留了不少遗留概念。
适合性能敏感、团队已熟悉它的项目。
安装
[dependencies]
actix-web = "4"
serde = { version = "1", features = ["derive"] }
最小示例
use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder};
use serde::{Deserialize, Serialize};
#[derive(Serialize)]
struct User { id: u64, name: String }
#[derive(Deserialize)]
struct CreateUser { name: String }
#[get("/")]
async fn hello() -> impl Responder {
HttpResponse::Ok().body("Hello")
}
#[get("/users/{id}")]
async fn get_user(path: web::Path<u64>) -> impl Responder {
HttpResponse::Ok().json(User { id: path.into_inner(), name: "demo".into() })
}
#[post("/users")]
async fn create_user(body: web::Json<CreateUser>) -> impl Responder {
HttpResponse::Created().json(User { id: 1, name: body.name.clone() })
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.service(hello)
.service(get_user)
.service(create_user)
})
.bind(("0.0.0.0", 8080))?
.run()
.await
}
核心概念
1. 宏路由
#[get("/path")]、#[post("/path")] 这些属性宏定义路由,和 Rocket 类似。
代价:出错时编译器的错误信息指向宏展开,不容易定位真实问题。
也可以不用宏,用显式路由:
App::new().route("/", web::get().to(hello))
2. 应用状态
struct AppState { db: Pool }
let state = web::Data::new(AppState { db: pool });
HttpServer::new(move || {
App::new()
.app_data(state.clone()) // 注册
.route("/", web::get().to(handler))
})
async fn handler(state: web::Data<AppState>) -> impl Responder {
// 用 state.db
HttpResponse::Ok()
}
web::Data 内部是 Arc,克隆很便宜。
3. 中间件
use actix_web::middleware::{Logger, Compressor, NormalizePath};
App::new()
.wrap(Logger::default())
.wrap(Compressor::default())
.wrap(NormalizePath::trim())
Actix 有自己的中间件 trait(Transform / Service),不能直接用 tower 的中间件。这是它和 Axum 的关键差异。
常见坑
① 路径参数语法
Actix 用 {id}(和其他 Rust 框架一致),但提取方式不同:web::Path<u64> 而不是 Axum 的 Path<u64>。
② web::Json 有默认大小限制
body 超过 2MB 会被拒,返回 413。要放宽得显式配置:
.app_data(web::JsonConfig::default().limit(10 * 1024 * 1024))
③ 中间件生态不能复用
tower 的中间件(tower-http 那一套)在 Actix 里用不了。要用 Actix 自己的实现,或者写适配层。
④ 历史上的 unsafe 争议
Actix 早期版本有过 unsafe 代码争议(社区曾因此分叉出 actix-web 的替代品)。现在已大幅改善,但选择时值得知道这段历史。
什么时候选它
- 性能是硬指标(压测数据要求极致)
- 团队已经熟悉 Actix 的 API 和中间件体系
- 不需要 tower 生态
不选它的场景:想要最主流的生态和最多的教程(选 Axum)、需要 tower 中间件、团队刚接触 Rust。
和 Axum 怎么选
| Axum | Actix Web | |
|---|---|---|
| 路由定义 | 函数式,route() | 属性宏 |
| 中间件 | tower 生态 | 自有 trait |
| 生态衔接 | 与 tokio/hyper/tower 天然一致 | 相对独立 |
| 性能 | 很强 | 略强 |
| 学习资料 | 多(主流选择) | 中等 |
| 错误信息 | 相对友好 | 宏展开后难定位 |
简单判断:新项目选 Axum。理由不是性能,是生态一致性和可维护性——tower 中间件、tokio 组件、sqlx 的组合是当前 Rust 后端的主流路线。
选 Actix 的理由只有一个:实际压测下来它确实快,而且这个差距对你的业务有意义。但先确认瓶颈真的在框架层,而不是数据库或序列化。