Rust 实战三 | HTTP 服务开发及 Web 框架推荐
往期回顾
- Rust 实战一 | 用 RustRover 开发猜数字游戏
- Rust 安装与版本更新
代码开源地址:https://github.com/0604hx/rust-journey
🚀 Web 框架
名称 | 性能(QPS) | WebSocket / SSE | GitHub ⭐ | 最新版本发布日期 | 备注说明 |
---|---|---|---|---|---|
Actix Web | 极高(wrk 单线程 QPS > 100k) | ✅ 内建支持 | ~23.5k | 2025‑07‑01 | 超高性能,适合高并发场景,actor 架构。 |
Axum | 很高(QPS > 200k,Tower 架构) | ✅ via 插件 / 自定义支持 | ~22.5k | 2025‑06‑10 | 类型安全,异步友好,生态活跃。 |
Warp | 较高(QPS > 200k) | ✅ warp_ws 插件 | ~9.9k | 2024‑12‑12 | 声明式路由,组合灵活。 |
Poem | 较高(接近 Warp 性能) | ✅ 内建支持(含 SSE) | ~4.1k | 2025-07-28 | 支持 OpenAPI、GraphQL 等,功能丰富。 |
Salvo | 中等(社区基准 QPS 偏低) | ✅ 内建支持 | ~3.8k | 2025‑07‑19 | 中文文档丰富,易上手,适合中小项目。 |
Rocket | 偏低(QPS < 160k,默认同步) | ✅ via tokio / 插件 | ~25.3k | 2024‑05‑24 | 简洁语法,适合原型开发和教学。 |
Tide | 中低(QPS ~127k,高并发性能下降明显) | ✅ via tide-websockets 插件 | ~5.1k | 约 2021‑01(v0.16) | async-std 驱动,轻量框架,适合入门学习。 |
Hyper | 极高 | ❌ 原生无 | ~15.4k | 2025‑06‑28 | 低级 HTTP 库,不是完整框架 |
📝 说明:
- 数据截至 2025-07
- 性能数据 来自社区 wrk 基准测试及 Rust Web Framework Benchmarks 等;
- WebSocket / SSE 支持 体现了原生或插件支持情况;
- GitHub 收藏数 为近似值,仅供参考;
- 最新版本发布日期 体现维护活跃度,Tide 暂无 1.0 稳定版。
Tokio
上述框架,好几个都是基于 tokio ,接下来我们了解下这个牛逼的库👍
在 Rust 的异步编程领域,Tokio 是一个核心基础设施,被众多 Web 框架(如 Axum、Actix、Warp 等)广泛采用。它是 Rust 生态中最流行的异步运行时,提供了高性能的异步任务调度、I/O 操作和网络编程能力。
Tokio 是什么?
Tokio 是 Rust 的异步运行时库,相当于异步程序的操作系统
,主要提供以下功能:
- 任务调度器:高效管理数百万个异步任务
- 非阻塞 I/O:文件、网络等操作的异步实现
- 工具库:包括定时器、信号处理、同步原语等
- 网络协议:内置 TCP、UDP、Unix Domain Socket 支持
为什么需要 Tokio?
Rust 的异步编程基于 Future 模型,需要运行时来驱动 Future 的执行。Tokio 提供了这个运行时环境,让开发者可以:
- 编写高效的异步代码,避免阻塞线程
- 处理海量并发连接(C10M 问题)
- 利用 Rust 的所有权系统保证异步代码的安全性
核心组件
1. 异步任务执行器(Executor)
use tokio::task;#[tokio::main] // 启动 Tokio 运行时
async fn main() {// 创建异步任务let handle = task::spawn(async {println!("异步任务正在执行");42});// 等待任务完成let result = handle.await.unwrap();println!("任务结果: {}", result);
}
Tokio 在 Web 框架中的应用
许多 Rust Web 框架选择 Tokio 作为底层运行时,因为:
- 高性能:Tokio 的任务调度器和 I/O 系统经过高度优化
- 生态丰富:大量异步库(如数据库驱动、HTTP 客户端)基于 Tokio 开发
- 稳定性:作为 Rust 异步生态的基石,Tokio 经过了严格测试和改进
🌏 HTTP 服务开发
salvo/国货之光
之所以放在第一位,纯粹是因为她是国产的 Web 框架,必须支持下😄
#![allow(unused_braces)]use std::time::{SystemTime, UNIX_EPOCH};
use salvo::{handler, Listener, Router, Server};
use salvo::prelude::TcpListener;#[handler]
async fn time()->String { format!("now is {}", SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()) }#[tokio::main]
async fn main() {let acceptor = TcpListener::new("0.0.0.0:8080").bind().await;let router = Router::new().get(time);println!("salvo web running on port 8080 ...");Server::new(acceptor).serve(router).await;
}
Actix Web/高性能
use std::time::{SystemTime, UNIX_EPOCH};
use actix_web::{get, App, HttpServer};#[get("/")]
async fn time()->String { format!("[actix-web] now is {}", SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()) }#[actix_web::main]
async fn main() -> std::io::Result<()> {HttpServer::new(|| App::new().service(time)).bind(("127.0.0.1", 8082))?.run().await
}
Axum/高性能新生代
use std::time::{SystemTime, UNIX_EPOCH};
use axum::Router;
use axum::routing::get;async fn time()->String { format!("[axum] now is {}", SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()) }#[tokio::main]
async fn main() {let app = Router::new().route("/", get(time));let listener = tokio::net::TcpListener::bind("0.0.0.0:8081").await.unwrap();println!("axum web running on port 8081 ...");axum::serve(listener, app).await.unwrap();
}
Rocket/简单易用
use std::time::{SystemTime, UNIX_EPOCH};#[macro_use] extern crate rocket;#[get("/")]
async fn time()->String { format!("[rocket] now is {}", SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()) }#[launch]
fn rocket() -> _ {rocket::build().mount("/", routes![time])
}
实际运行对比
综合来看,个人觉得 axum
确实很优秀👍。
⚒️cargo 多二进制(multi-bin)结构
在项目的 src/bin
目录下放多个 Rust 文件,每个文件都可以有自己的 main 函数,cargo 会把它们当作独立的二进制程序编译。
示例结构:
my-project/
├── Cargo.toml
└── src/├── main.rs ← 默认的 main└── bin/├── task1.rs ← 一个 main 函数└── task2.rs ← 另一个 main 函数
编译和运行:
cargo run --bin task1
cargo run --bin task2
为什么需要
我在rust-journey项目中,子模块j03_web
是本文相关的代码,希望在该模块内演示多个 Web 框架的基础使用,于是就想有多个 main
入口程序。