跳到主要内容

设计 API 网关

问题

如何用 Rust 设计一个 API 网关?

答案

架构设计

基于 Axum + Tower 的网关

use axum::{Router, middleware, routing::any};
use tower::ServiceBuilder;
use std::collections::HashMap;

/// 路由配置
struct GatewayConfig {
routes: Vec<RouteRule>,
}

struct RouteRule {
prefix: String, // e.g. "/api/users"
upstream: String, // e.g. "http://user-service:3000"
rate_limit: Option<u32>, // 每秒请求数
auth_required: bool,
}

fn build_gateway(config: GatewayConfig) -> Router {
let mut router = Router::new();

for rule in config.routes {
let upstream = rule.upstream.clone();

// 为每个路由创建处理函数
let handler = any(move |req: axum::extract::Request| {
let upstream = upstream.clone();
async move {
// 转发请求到上游服务
let client = reqwest::Client::new();
let path = req.uri().path_and_query()
.map(|pq| pq.as_str())
.unwrap_or("/");
let url = format!("{}{}", upstream, path);

match client.request(req.method().clone(), &url)
.headers(req.headers().clone())
.send()
.await
{
Ok(resp) => {
let status = resp.status();
let body = resp.text().await.unwrap_or_default();
(status, body).into_response()
}
Err(_) => {
axum::http::StatusCode::BAD_GATEWAY.into_response()
}
}
}
});

router = router.route(&format!("{}/*rest", rule.prefix), handler);
}

// 全局中间件链
router.layer(
ServiceBuilder::new()
.layer(middleware::from_fn(logging_middleware))
.layer(middleware::from_fn(metrics_middleware))
)
}

网关核心功能

功能实现方式
路由转发前缀匹配 → 上游服务
认证JWT 验证中间件
限流Tower RateLimit / 自定义令牌桶
熔断Tower Circuit Breaker
请求改写中间件修改 Header/Body
协议转换HTTP ↔ gRPC
负载均衡Round-Robin / P2C
监控Prometheus metrics

常见面试问题

Q1: API 网关与反向代理的区别?

答案

维度反向代理API 网关
关注点流量转发业务治理
功能负载均衡、缓存认证、限流、熔断、协议转换
路由URL → 后端URL + Header + 规则 → 微服务
配置静态动态(配置中心)
典型实现NginxKong、Envoy、自研

API 网关 = 反向代理 + 业务治理层。

相关链接