企业信息化管理系统

EIMS - 助力企业数字化转型

企业信息化系统 API 网关设计与实现

为什么需要 API 网关

随着企业信息化系统规模的扩大,微服务架构下服务数量急剧增加。API 网关作为统一入口,承担着认证授权、流量管控、协议转换、监控告警等核心功能,是微服务架构中不可或缺的组件。

网关核心功能

功能模块 说明 实现方式
身份认证 验证请求合法性 JWT、OAuth2、Session
权限校验 校验用户权限 RBAC、ABAC
限流熔断 保护后端服务 令牌桶、滑动窗口
路由转发 请求分发到后端 路径、Header、参数
日志监控 记录请求日志 ELK、Prometheus

Kong 网关部署配置

Kong 是流行的开源 API 网关,以下是基于 Nginx 的简化实现方案:

1. Nginx 网关配置

upstream backend_oa {
    server oa-service:8080;
    keepalive 32;
}

upstream backend_erp {
    server erp-service:8080;
    keepalive 32;
}

upstream backend_crm {
    server crm-service:8080;
    keepalive 32;
}

server {
    listen 80;
    server_name api.eims.js.cn;

    # 请求体大小限制
    client_max_body_size 10M;

    # 限流配置 - 令牌桶
    limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/s;

    location /oa/ {
        # JWT 认证
        auth_jwt "EIMS API" keyring;

        # 限流
        limit_req zone=api_limit burst=20 nodelay;

        # 路由转发
        rewrite ^/oa/(.*) /$1 break;
        proxy_pass http://backend_oa/;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }

    location /erp/ {
        auth_jwt "EIMS API" keyring;
        limit_req zone=api_limit burst=20 nodelay;
        rewrite ^/erp/(.*) /$1 break;
        proxy_pass http://backend_erp/;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }

    location /crm/ {
        auth_jwt "EIMS API" keyring;
        limit_req zone=api_limit burst=20 nodelay;
        rewrite ^/crm/(.*) /$1 break;
        proxy_pass http://backend_crm/;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }

    # 健康检查
    location /health {
        access_log off;
        return 200 "OK";
    }
}

2. JWT 认证中间件

// JWT 验证函数
function verifyJwt(token, secret) {
    try {
        const decoded = jwt.verify(token, secret, {
            algorithms: ['HS256', 'RS256']
        });
        return decoded;
    } catch (err) {
        return null;
    }
}

// 请求拦截处理
async function gatewayMiddleware(ctx, next) {
    const path = ctx.path;

    // 跳过健康检查和公开接口
    if (path === '/health' || path.startsWith('/public/')) {
        return await next();
    }

    // 获取 Token
    const token = ctx.get('Authorization')?.replace('Bearer ', '');
    if (!token) {
        ctx.status = 401;
        ctx.body = { error: '缺少认证令牌' };
        return;
    }

    // 验证 Token
    const user = verifyJwt(token, process.env.JWT_SECRET);
    if (!user) {
        ctx.status = 401;
        ctx.body = { error: '认证令牌无效' };
        return;
    }

    // 权限校验
    const requiredPermission = getRequiredPermission(path, ctx.method);
    if (requiredPermission && !user.permissions.includes(requiredPermission)) {
        ctx.status = 403;
        ctx.body = { error: '权限不足' };
        return;
    }

    // 注入用户信息
    ctx.state.user = user;
    await next();
}

限流与熔断策略

1. 限流算法实现

// 令牌桶算法实现
class TokenBucket {
    constructor(capacity, refillRate) {
        this.capacity = capacity;      // 桶容量
        this.tokens = capacity;        // 当前令牌数
        this.refillRate = refillRate;  // 每秒补充令牌数
        this.lastRefill = Date.now();
    }

    tryConsume(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;
        const tokensToAdd = elapsed * this.refillRate;

        this.tokens = Math.min(this.capacity, this.tokens + tokensToAdd);
        this.lastRefill = now;
    }
}

2. 熔断器模式

// 熔断器实现
class CircuitBreaker {
    constructor(threshold, timeout) {
        this.threshold = threshold;    // 失败阈值
        this.timeout = timeout;        // 熔断时长(毫秒)
        this.failCount = 0;
        this.state = 'CLOSED';         // CLOSED, OPEN, HALF_OPEN
        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 (err) {
            this.onFailure();
            throw err;
        }
    }

    onSuccess() {
        this.failCount = 0;
        this.state = 'CLOSED';
    }

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

监控与告警

总结

API 网关是企业信息化系统的统一入口,通过合理的网关设计可以实现认证授权、限流熔断、日志监控等核心功能。建议根据实际业务规模选择合适的实现方案,对于中小型系统可以采用 Nginx + Lua 方案,大型复杂系统建议使用 Kong、APISIX 等专业网关。

← 下一篇:企业信息化系统微服务拆分实践