IMS系统API网关完全指南

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实现无状态认证