API网关是IMS系统的统一入口,负责请求路由、限流熔断、认证鉴权等功能。本文详细介绍API网关的设计与实现。
网关核心功能
API网关的主要职责:
- 请求路由:将请求路由到对应的后端服务
- 负载均衡:分发请求到多个服务实例
- 限流熔断:保护后端服务不被过载
- 认证鉴权:验证请求的合法性
- 日志审计:记录请求日志用于分析
请求路由
基于路径和参数的动态路由:
/* 路由配置 */
interface RouteConfig {
path: string;
method: string;
upstream: string;
timeout: number;
retry?: number;
}
/* 路由匹配规则 */
class RouteMatcher {
private routes: RouteConfig[] = [];
addRoute(config: RouteConfig) {
this.routes.push(config);
}
match(path: string, method: string): RouteConfig | null {
/* 精确匹配 */
let route = this.routes.find(
r => r.path === path && r.method === method
);
if (route) return route;
/* 参数匹配:/api/users/:id */
for (const r of this.routes) {
const pattern = this.toRegex(r.path);
if (pattern.test(path) && r.method === method) {
return r;
}
}
return null;
}
toRegex(path: string): RegExp {
return new RegExp(
'^' + path.replace(/:(\w+)/g, '(?<$1>[^/]+)') + '$'
);
}
}
/* 初始化路由 */
const routeMatcher = new RouteMatcher();
routeMatcher.addRoute({
path: "/api/users",
method: "GET",
upstream: "user-service:8080",
timeout: 5000
});
routeMatcher.addRoute({
path: "/api/orders",
method: "POST",
upstream: "order-service:8080",
timeout: 10000
});
限流实现
使用令牌桶算法实现限流:
/* 令牌桶限流器 */
class TokenBucketRateLimiter {
constructor(
private capacity: number, // 桶容量 */
private refillRate: number // 每秒添加的令牌数 */
) {
this.tokens = capacity;
}
private tokens: number;
private lastRefill: number = Date.now();
tryAcquire(tokens: number = 1): boolean {
/* 补充令牌 */
this.refill();
if (this.tokens >= tokens) {
this.tokens -= tokens;
return true;
}
return false;
}
refill() {
const now = Date.now();
const elapsed = (now - this.lastRefill) / 1000;
const newTokens = elapsed * this.refillRate;
this.tokens = Math.min(this.capacity, this.tokens + newTokens);
this.lastRefill = now;
}
}
/* 按用户限流 */
class UserRateLimiter {
private limiters: Map<string, TokenBucketRateLimiter> = new Map();
check(userId: string, limit: number, windowSec: number): boolean {
let limiter = this.limiters.get(userId);
if (!limiter) {
limiter = new TokenBucketRateLimiter(limit, limit / windowSec);
this.limiters.set(userId, limiter);
}
return limiter.tryAcquire();
}
}
熔断机制
使用熔断器模式保护下游服务:
/* 熔断器状态 */
enum CircuitState {
CLOSED = "closed", // 正常 */
OPEN = "open", // 熔断中 */
HALF_OPEN = "half_open" // 半开,允许请求 */
}
/* 熔断器 */
class CircuitBreaker {
constructor(
private failureThreshold: number = 5,
private successThreshold: number = 3,
private timeout: number = 30000
) {
this.state = CircuitState.CLOSED;
}
private state: CircuitState;
private failureCount = 0;
private successCount = 0;
private lastFailureTime = 0;
isAvailable(): boolean {
if (this.state === CircuitState.CLOSED) {
return true;
}
/* 检查是否需要从OPEN转到HALF_OPEN */
if (this.state === CircuitState.OPEN) {
if (Date.now() - this.lastFailureTime > this.timeout) {
this.state = CircuitState.HALF_OPEN;
return true;
}
return false;
}
/* HALF_OPEN状态只允许通过一个请求 */
return true;
}
recordSuccess() {
if (this.state === CircuitState.HALF_OPEN) {
this.successCount++;
if (this.successCount >= this.successThreshold) {
this.state = CircuitState.CLOSED;
this.failureCount = 0;
this.successCount = 0;
}
} else {
this.failureCount = 0;
}
}
recordFailure() {
this.lastFailureTime = Date.now();
this.failureCount++;
this.successCount = 0;
if (this.failureCount >= this.failureThreshold) {
this.state = CircuitState.OPEN;
}
}
}
认证鉴权
JWT令牌验证与权限检查:
/* JWT验证器 */
class JWTValidator {
verify(token: string, secret: string): any {
try {
const parts = token.split('.');
if (parts.length !== 3) return null;
const payload = JSON.parse(
Buffer.from(parts[1], 'base64').toString()
);
/* 验证签名 */
const signature = this.sign(parts[0] + '.' + parts[1], secret);
if (signature !== parts[2]) return null;
/* 检查过期 */
if (payload.exp && payload.exp < Date.now() / 1000) {
return null;
}
return payload;
} catch (e) {
return null;
}
}
extractToken(authHeader: string): string | null {
if (!authHeader.startsWith('Bearer ')) {
return null;
}
return authHeader.substring(7);
}
}
/* 权限检查 */
class PermissionChecker {
check(user: any, resource: string, action: string): boolean {
/* 超级管理员拥有所有权限 */
if (user.role === "admin") return true;
/* 检查用户权限列表 */
const permission = `${resource}:${action}`;
return user.permissions?.includes(permission) ?? false;
}
}
网关中间件
使用中间件链处理请求:
/* 中间件类型 */
type Middleware = (
ctx: Context,
next: () => Promise<void>
) => Promise<void>;
/* 中间件组合 */
class MiddlewareChain {
private middlewares: Middleware[] = [];
use(middleware: Middleware) {
this.middlewares.push(middleware);
}
execute(ctx: Context) {
let index = 0;
const next = async () => {
if (index >= this.middlewares.length) return;
const middleware = this.middlewares[index++];
await middleware(ctx, next);
};
return next();
}
}
/* 使用示例:注册中间件 */
const chain = new MiddlewareChain();
chain.use(loggerMiddleware); // 日志 */
chain.use(rateLimitMiddleware); // 限流 */
chain.use(authMiddleware); // 认证 */
chain.use(routeMiddleware); // 路由 */
网关部署建议
- 使用多实例部署保证高可用
- 限流阈值根据后端服务能力设置
- 熔断恢复后逐步放量
- 做好监控告警,及时发现异常
总结
- 请求路由基于配置动态匹配
- 令牌桶算法实现精确限流
- 熔断器保护下游服务
- JWT实现无状态认证