Rust Web 后端开发实战:Actix + Diesel 构建高性能 API
《一条龙开发指南:MCP AI Agent 理论+项目实战开发你的MCP Server》
🧑💻 面试人物设定
- 姓名: 徐子昂
- 年龄: 32 岁
- 学历: 计算机硕士
- 工作年限: 7 年
- 公司背景: 某头部金融科技平台
- 技术栈: Rust, Actix, Diesel, PostgreSQL, JWT, Redis
- 核心职责:
- 使用 Rust 开发高并发后端服务
- 利用 Actix 框架实现 Web 接口
- 接入 Diesel 实现数据库访问
- 使用 JWT 实现用户鉴权机制
- 工作成果:
- 成功上线多个交易接口模块,QPS 提升 60%
- 将平均响应时间缩短至 80ms 内
🎤 第一轮面试:Rust Web 基础考察
面试官: “你好,请介绍一下你最近参与的 Rust 项目。”
程序员: “您好!我最近主要负责一个基于 Actix 和 Diesel 的用户管理服务重构项目,使用 JWT 实现身份验证,并接入 Redis 缓存高频查询结果,整体系统具备良好的性能与稳定性。”
面试官: “你能写一个简单的 Actix 路由吗?”
程序员: “当然可以,比如定义一个 GET 接口返回 JSON 数据。”
// main.rs
use actix_web::{web, App, HttpServer, Responder};
async fn greet(name: web::Path<String>) -> impl Responder {
format!("Hello, {}!", name)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/greet/{name}", web::get().to(greet))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
🧠 第二轮面试:Diesel 数据库操作
面试官: “你是怎么使用 Diesel 的?”
程序员: “我们会使用 Diesel 定义数据模型,并进行数据库操作。”
# 创建迁移脚本
diesel migration generate --name create_users
-- up.sql
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
email VARCHAR UNIQUE NOT NULL,
password_hash VARCHAR NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- down.sql
DROP TABLE users;
// models.rs
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Queryable)]
pub struct User {
pub id: i32,
pub name: String,
pub email: String,
pub created_at: chrono::NaiveDateTime,
}
#[derive(Insertable)]
#[table_name = "users"]
pub struct NewUser<'a> {
pub name: &'a str,
pub email: &'a str,
pub password_hash: &'a str,
}
// handlers.rs
use actix_web::{web, HttpResponse};
use diesel::prelude::*;
use serde_json::json;
use crate::models::User;
use crate::schema::users;
pub async fn get_users(pool: web::Data<Pool<Connection = PgConnection>>) -> HttpResponse {
let connection = pool.get().expect("Failed to get DB connection from pool");
let results = web::block(move || {
users::table.load::<User>(&connection)
})
.await
.map_err(|e| {
eprintln!("Error loading users: {}", e);
HttpResponse::InternalServerError().finish()
});
match results {
Ok(users) => HttpResponse::Ok().json(json!({ "users": users })),
Err(e) => e,
}
}
⚙️ 第三轮面试:JWT 用户认证
面试官: “你们是怎么实现用户认证的?”
程序员: “我们使用 jsonwebtoken
库实现 Token 签发与验证。”
// auth.rs
use jsonwebtoken::{encode, decode, Header, Validation};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
sub: String,
exp: u64,
}
fn generate_token(user_id: &str) -> Result<String, jsonwebtoken::errors::Error> {
let claims = Claims {
sub: user_id.to_string(),
exp: 10000000000, // 设置过期时间
};
encode(&Header::default(), &claims, b"secret_key")
}
fn verify_token(token: &str) -> Result<Claims, jsonwebtoken::errors::Error> {
decode::<Claims>(token, b"secret_key", &Validation::default())
.map(|data| data.claims)
}
📊 第四轮面试:Redis 缓存加速
面试官: “你是怎么使用 Redis 的?”
程序员: “我们使用 redis-rs
库实现缓存机制。”
// cache.rs
use redis::{Client, Commands};
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug)]
struct CachedUser {
id: i32,
name: String,
email: String,
}
fn set_user_cache(client: &Client, user: &CachedUser) -> redis::RedisResult<()> {
let key = format!("user:{}", user.id);
let serialized = serde_json::to_string(user).unwrap();
let mut con = client.get_connection().unwrap();
con.set_ex(key, serialized, 3600) // 缓存 1 小时
}
fn get_user_cache(client: &Client, user_id: i32) -> Option<CachedUser> {
let key = format!("user:{}", user_id);
let mut con = client.get_connection().unwrap();
let data: Option<String> = con.get(key).unwrap();
data.and_then(|d| serde_json::from_str(&d).ok())
}
📈 第五轮面试:服务部署与监控
面试官: “你是怎么部署服务的?”
程序员: “我们主要使用 Docker 容器化部署,并结合 Prometheus + Grafana 实现可视化监控。”
# Dockerfile
FROM rust:latest as builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:buster-slim
WORKDIR /app
COPY --from=builder /app/target/release/myserver ./
CMD ["./myserver"]
# 构建镜像
docker build -t rust-api-service:latest .
# 启动容器
docker run -d -p 8080:8080 --name rust-api rust-api-service:latest
💬 结尾环节
面试官: “今天的面试就到这里,我们会综合评估你的表现,后续 HR 会联系你。”
程序员: “谢谢您今天的时间,期待有机会加入贵公司。”