PSI进销存系统API网关设计与流量管控
API网关的作用
API网关是系统的统一入口,承担着请求路由、认证授权、限流熔断、日志监控等核心功能。在分布式架构中,网关是连接客户端与后端服务的桥梁,合理的网关设计能够有效保护后端服务、提升系统安全性、简化客户端调用。PSI进销存系统采用自研API网关,实现了对所有服务的统一管控。
网关核心功能
- 请求路由:根据URL路径或参数将请求路由到对应的后端服务
- 负载均衡:将请求分发到多个服务实例,支持多种负载策略
- 认证授权:统一处理用户认证和权限校验
- 限流熔断:防止系统被高并发请求压垮
- 请求日志:记录所有请求用于分析、监控和问题排查
- 协议转换:支持HTTP、RPC、WebSocket等多种协议
网关架构设计
| 层次 | 功能模块 | 技术实现 |
|---|---|---|
| 接入层 | 负载均衡、SSL卸载 | Nginx |
| 网关层 | 路由、认证、限流 | Koa / Express |
| 服务层 | 业务逻辑处理 | 微服务集群 |
| 数据层 | 数据存储与缓存 | MySQL / Redis |
请求路由实现
网关根据配置将请求路由到对应的后端服务:
// 路由配置
const routes = [
{
path: '/api/order/*',
service: 'order-service',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
timeout: 5000,
retry: 2
},
{
path: '/api/inventory/*',
service: 'inventory-service',
methods: ['GET', 'POST', 'PUT'],
timeout: 3000,
retry: 1
},
{
path: '/api/product/*',
service: 'product-service',
methods: ['GET', 'POST'],
timeout: 5000,
cache: true,
cacheTTL: 60
},
{
path: '/api/payment/*',
service: 'payment-service',
methods: ['POST'],
timeout: 10000,
auth: true,
rateLimit: { points: 10, duration: 60 }
}
];
// 路由匹配中间件
async function routeMiddleware(ctx, next) {
const matchedRoute = routes.find(r =>
matchPath(ctx.path, r.path) &&
r.methods.includes(ctx.method)
);
if (!matchedRoute) {
ctx.status = 404;
ctx.body = { error: 'API not found' };
return;
}
// 设置路由上下文
ctx.route = matchedRoute;
// 负载均衡选择服务实例
const instance = loadBalancer.select(matchedRoute.service);
ctx.upstream = `${instance.host}:${instance.port}`;
await next();
}
认证授权机制
统一的认证授权保护后端服务安全:
// 认证中间件
async function authMiddleware(ctx, next) {
// 1. 检查是否需要认证
if (!ctx.route.auth) {
return next();
}
// 2. 获取Token
const token = ctx.headers.authorization?.replace('Bearer ', '');
if (!token) {
ctx.status = 401;
ctx.body = { error: 'Missing authorization token' };
return;
}
try {
// 3. 验证Token
const decoded = jwt.verify(token, JWT_SECRET);
// 4. 获取用户权限
const permissions = await getUserPermissions(decoded.userId);
// 5. 检查接口权限
const requiredPermission = getRequiredPermission(ctx.path, ctx.method);
if (!permissions.includes(requiredPermission)) {
ctx.status = 403;
ctx.body = { error: 'Insufficient permissions' };
return;
}
// 6. 设置用户上下文
ctx.user = {
id: decoded.userId,
role: decoded.role,
permissions: permissions
};
await next();
} catch (err) {
ctx.status = 401;
ctx.body = { error: 'Invalid or expired token' };
}
}
限流策略实现
使用令牌桶算法实现灵活的限流控制:
| 限流维度 | 配置方式 | 适用场景 |
|---|---|---|
| 全局限流 | 按IP地址统计 | 防止单IP攻击 |
| 用户限流 | 按用户ID统计 | 控制用户请求频率 |
| 接口限流 | 按API路径配置 | 保护高负载接口 |
| VIP限流 | VIP用户更高配额 | 差异化服务 |
熔断降级策略
防止服务故障导致系统雪崩:
// 熔断器实现
class CircuitBreaker {
constructor(options) {
this.failureThreshold = options.failureThreshold || 5;
this.successThreshold = options.successThreshold || 2;
this.timeout = options.timeout || 60000; // 熔断时间
this.state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN
this.failures = 0;
this.lastFailureTime = null;
}
async execute(fn) {
if (this.state === 'OPEN') {
if (Date.now() - this.lastFailureTime > this.timeout) {
this.state = 'HALF_OPEN';
} else {
throw new Error('Circuit breaker is OPEN');
}
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (err) {
this.onFailure();
throw err;
}
}
onSuccess() {
this.failures = 0;
if (this.state === 'HALF_OPEN') {
this.state = 'CLOSED';
}
}
onFailure() {
this.failures++;
this.lastFailureTime = Date.now();
if (this.failures >= this.failureThreshold) {
this.state = 'OPEN';
}
}
}
请求监控与告警
实时监控网关运行状态,及时发现和处理异常:
- 请求指标:QPS、响应时间、错误率、流量趋势
- 服务健康:后端服务可用性、响应时间分布
- 限流统计:被限流请求数、限流触发原因
- 异常告警:错误率超阈值、服务超时、熔断触发
灰度发布支持
网关支持金丝雀发布和平滑回滚:
- 流量比例:按百分比将流量导向新版本
- 用户分组:特定用户组先使用新功能
- 请求特征:根据请求参数决定路由版本
- 自动回滚:异常指标超阈值自动回滚到旧版本