架构设计

IMS系统API网关设计完全指南

API 网关是微服务架构的核心组件,承担着请求路由、认证授权、限流熔断、日志监控等功能。本文详细介绍 IMS 系统的 API 网关设计与实现。

一、API 网关概述

API 网关是系统的统一入口,所有外部请求都经过网关转发到后端服务。主要功能包括:

  • 请求路由:根据路径、参数将请求路由到对应服务
  • 认证授权:验证 Token、检查权限
  • 限流熔断:保护后端服务,防止过载
  • 日志监控:记录请求日志,便于分析
  • 协议转换:支持 HTTP、gRPC、WebSocket 等

二、网关架构设计

/* API 网关架构 */
┌─────────────────────────────────────────────────────┐
│                    API Gateway                      │
├─────────────────────────────────────────────────────┤
│  ┌──────────┐  ┌──────────┐  ┌──────────┐         │
│  │  请求    │  │  路由    │  │  认证    │         │
│  │  解析    │  │  转发    │  │  拦截    │         │
│  └──────────┘  └──────────┘  └──────────┘         │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐         │
│  │  限流    │  │  熔断    │  │  日志    │         │
│  │  控制    │  │  保护    │  │  记录    │         │
│  └──────────┘  └──────────┘  └──────────┘         │
└───────────────────────┬─────────────────────────────┘
                        
┌──────────────┬──────────────┬──────────────┐
│ 用户服务     │ 订单服务     │ 商品服务     │
│ /api/user    │ /api/order   │ /api/product │
└──────────────┴──────────────┴──────────────┘

三、请求路由实现

/* 路由配置 */
const routes = [
  {
    "path": "/api/user/**",
    "service": "user-service",
    "version": "v2",
    "timeout": 5000
  },
  {
    "path": "/api/order/**",
    "service": "order-service",
    "version": "v1",
    "timeout": 10000
  },
  {
    "path": "/api/product/**",
    "service": "product-service",
    "stripPath": true
  }
];

/* 路由匹配逻辑 */
function matchRoute(path) {
  for (const route of routes) {
    if (matchPath(path, route.path)) {
      return route;
    }
  }
  return null;
}

四、认证授权

/* 认证中间件 */
async authMiddleware(ctx, next) {
  // 1. 提取 Token
  const token = extractToken(ctx.get('Authorization'));

  if (!token) {
    return ctx.throw(401, '缺少认证令牌');
  }

  // 2. 验证 Token
  try {
    const payload = jwt.verify(token, SECRET_KEY);
    ctx.user = payload;
  } catch (e) {
    return ctx.throw(401, '无效的认证令牌');
  }

  // 3. 检查权限
  const requiredPermission = getRequiredPermission(ctx.get('path'), ctx.get('method'));
  if (requiredPermission && !ctx.user.permissions.includes(requiredPermission)) {
    return ctx.throw(403, '权限不足');
  }

  // 4. 放行
  await next();
}

权限模型设计

操作说明
user:read查看用户
user:create创建用户
user:update修改用户
user:delete删除用户
order:*订单所有操作
最佳实践:
  • 使用 JWT Token,支持分布式验证
  • Token 短期有效,refresh token 长期有效
  • 敏感接口增加二次验证(短信、邮件)

五、限流策略

/* 限流器实现 - 令牌桶 */
class TokenBucket {
  constructor(rate, capacity) {
    this.rate = rate;        // 每秒添加的令牌数
    this.capacity = capacity; // 桶的容量
    this.tokens = capacity;
    this.lastRefill = Date.now();
  }

  consume(tokens = 1) {
    this.refill();

    if (this.tokens >= tokens) {
      this.tokens -= tokens;
      return true;
    }

    return false;  // 被限流
  }

  refill() {
    const now = Date.now();
    const elapsed = (now - this.lastRefill) / 1000;
    this.tokens = Math.min(this.capacity, this.tokens + elapsed * this.rate);
    this.lastRefill = now;
  }
}

/* 全局限流配置 */
const globalLimiter = new TokenBucket(1000, 2000); // 1000 QPS

/* 端点限流配置 */
const endpointLimiters = {
  'POST /api/order': new TokenBucket(50, 100),
  'POST /api/user/login': new TokenBucket(5, 10)
};

六、熔断保护

/* 熔断器实现 */
class CircuitBreaker {
  constructor(options) {
    this.failureThreshold = options.failureThreshold || 5;
    this.successThreshold = options.successThreshold || 2;
    this.timeout = options.timeout || 30000;
    this.state = 'CLOSED';  // CLOSED/OPEN/HALF_OPEN
    this.failures = 0;
    this.successes = 0;
    this.nextAttempt = 0;
  }

  async execute(fn) {
    if (this.state === 'OPEN') {
      if (Date.now() < this.nextAttempt) {
        throw new Error('服务不可用 (熔断打开)');
      }
      this.state = 'HALF_OPEN';
    }

    try {
      const result = await fn();
      this.onSuccess();
      return result;
    } catch (e) {
      this.onFailure();
      throw e;
    }
  }

  onSuccess() {
    if (this.state === 'HALF_OPEN') {
      this.successes++;
      if (this.successes >= this.successThreshold) {
        this.state = 'CLOSED';
        this.failures = 0;
        this.successes = 0;
      }
    }
  }

  onFailure() {
    this.failures++;
    if (this.failures >= this.failureThreshold) {
      this.state = 'OPEN';
      this.nextAttempt = Date.now() + this.timeout;
    }
  }
}

七、日志与监控

/* 请求日志记录 */
async loggingMiddleware(ctx, next) {
  const startTime = Date.now();
  const requestId = generateId();

  ctx.set('X-Request-ID', requestId);

  try {
    await next();

    // 记录成功日志
    logger.info({
      requestId,
      method: ctx.method,
      path: ctx.path,
      status: ctx.status,
      duration: Date.now() - startTime,
      userId: ctx.user?.id
    });
  } catch (e) {
    // 记录错误日志
    logger.error({
      requestId,
      method: ctx.method,
      path: ctx.path,
      error: e.message,
      stack: e.stack,
      duration: Date.now() - startTime
    });
    throw e;
  }
}

八、总结

  • API 网关是系统统一入口,负责请求路由、认证、限流等功能
  • 路由配置支持路径匹配、服务版本、超时设置
  • 认证采用 JWT,结合权限模型实现细粒度授权
  • 限流使用令牌桶算法,支持全局和端点级别限流
  • 熔断器保护后端服务,防止故障扩散
  • 完善的日志记录有助于问题排查和性能分析