用“幼儿园活动日”比喻理解 API 网关三大核心功能
1. 什么是“限流”“认证”“路由转发”?
想象幼儿园的“活动日”:
- 认证(查门票):保安在门口检查每个小朋友的门票,只有票上写着名字的小朋友才能进入。
- 限流(控制人数):保安发现活动室里已经有 20 个小朋友了,就暂时不让其他人进去,等有人出来再放新的小朋友进去。
- 路由转发(指引方向):小朋友问保安:“手工区在哪里?”保安看了看地图,告诉小朋友:“直走左转就是。”
2. 三大功能包含哪些部分?
画一个“幼儿园活动日管理系统”示意图:
┌───────────────────────────┐
│ API 网关核心功能 │
├───────────────────────────┤
│ 查票员:认证系统 │
│ ├─ 检查门票(Token) │
│ ├─ 验证身份有效性 │
│ └─ 拒绝无效访问 │
│ │
│ 人数控制员:限流系统 │
│ ├─ 统计当前人数 │
│ ├─ 判断是否超过限制 │
│ └─ 限制或放行请求 │
│ │
│ 地图指引员:路由系统 │
│ ├─ 接收请求 │
│ ├─ 查找对应区域 │
│ └─ 指引正确方向 │
└───────────────────────────┘
3. 代码演示:三大功能实现
下面是 Hyperf 中实现这三大功能的简化代码:
<?php
// 1. 认证功能(查门票)
// 文件名:app/Middleware/AuthMiddleware.php
class AuthMiddleware {
public function process($request, $handler) {
// 从请求头中获取门票(Token)
$token = $request->getHeaderLine('Authorization');
// 检查门票是否存在(就像检查小朋友有没有带票)
if (empty($token)) {
return response()->json(['message' => '请出示门票'], 401);
}
// 验证门票有效性(就像检查票上的名字和照片)
$isValid = $this->verifyToken($token);
if (!$isValid) {
return response()->json(['message' => '无效门票'], 403);
}
// 门票有效,放行请求(就像让小朋友进入幼儿园)
return $handler->handle($request);
}
private function verifyToken($token) {
// 这里应该调用实际的认证服务
// 简化为检查Token是否以"VALID_"开头
return str_starts_with($token, 'VALID_');
}
}
// 2. 限流功能(控制人数)
// 文件名:app/Middleware/RateLimitMiddleware.php
class RateLimitMiddleware {
private $maxRequests = 100; // 每分钟最多100个请求
private $timeWindow = 60; // 时间窗口60秒
public function process($request, $handler) {
// 获取访问者IP(就像记住小朋友的学号)
$ip = $request->getServerParams()['remote_addr'];
// 使用Redis记录访问次数(就像用本子记录每个小朋友进活动室的次数)
$redis = redis();
$key = "rate_limit:{$ip}";
// 获取当前访问次数
$count = $redis->incr($key);
// 设置过期时间(第一次访问时)
if ($count === 1) {
$redis->expire($key, $this->timeWindow);
}
// 判断是否超过限制(就像判断活动室里的人数是否超过20)
if ($count > $this->maxRequests) {
return response()->json(['message' => '访问太频繁,请稍后再试'], 429);
}
// 未超过限制,放行请求
return $handler->handle($request);
}
}
// 3. 路由转发(指引方向)
// 文件名:config/routes.php
Router::addRoute(['GET', 'POST', 'PUT', 'DELETE'], '/api/{service}/{action}', function ($request) {
// 获取请求的服务和动作(就像小朋友问保安要去哪个区域)
$service = $request->getAttribute('service');
$action = $request->getAttribute('action');
// 服务映射表(就像保安手里的活动室地图)
$serviceMap = [
'user' => 'http://user-service:9501', // 用户服务
'order' => 'http://order-service:9502', // 订单服务
'product' => 'http://product-service:9503', // 商品服务
];
// 检查服务是否存在(就像保安确认活动室里有没有这个区域)
if (!isset($serviceMap[$service])) {
return response()->json(['message' => '服务不存在'], 404);
}
// 构建目标URL(就像保安告诉小朋友具体位置)
$targetUrl = "{$serviceMap[$service]}/{$action}";
// 转发请求(就像保安带小朋友去对应的活动室)
$client = new \GuzzleHttp\Client();
$response = $client->request(
$request->getMethod(),
$targetUrl,
[
'headers' => $request->getHeaders(),
'body' => $request->getBody(),
]
);
// 返回响应(就像小朋友完成活动后回来告诉保安结果)
return response()->raw($response->getBody());
});
4. 三大功能背后做了什么?
用“幼儿园活动日”比喻:
认证时:
- 保安在门口检查每个小朋友的门票(从请求头中获取 Token);
- 看看票上有没有名字和照片(验证 Token 是否有效);
- 如果票是假的或者过期了,不让小朋友进去(返回 401/403 错误);
- 如果票没问题,让小朋友进去(放行请求)。
限流时:
- 保安用本子记录每个小朋友进入活动室的次数(用 Redis 记录请求次数);
- 如果发现某个小朋友在 1 分钟内进了 20 次,就不让他再进了(返回 429 错误);
- 1 分钟后,本子上的记录清零(Redis 键过期),小朋友可以重新开始计数。
路由转发时:
- 小朋友问保安:“手工区在哪里?”(客户端发送请求到网关);
- 保安查看活动室地图(服务映射表),找到手工区在三楼左转(找到对应的后端服务);
- 保安带小朋友去手工区(网关转发请求到后端服务);
- 小朋友完成手工后,回来告诉保安结果(后端服务返回响应给网关);
- 保安把结果告诉其他小朋友(网关返回响应给客户端)。
5. 使用场景
-
认证:
- 保护API,防止未授权访问;
- 验证用户身份,确保数据安全;
- 单点登录(SSO)系统。
-
限流:
- 防止API被恶意攻击(如DDOS);
- 保护后端服务,避免被过量请求压垮;
- 控制资源使用,公平分配服务能力。
-
路由转发:
- 统一API入口,简化客户端调用;
- 服务发现与负载均衡;
- 微服务架构中,将请求导向正确的服务。
思维导图:三大核心功能
┌───────────────────┐
│ API网关三大功能 │
│ (幼儿园活动日) │
├───────────────────┤
│ 认证(查门票): │
│ ├─ 检查Token │
│ ├─ 验证有效性 │
│ └─ 拒绝非法访问 │
│ │
│ 限流(控人数): │
│ ├─ 统计请求次数 │
│ ├─ 判断阈值 │
│ └─ 限制超额请求 │
│ │
│ 路由(指方向): │
│ ├─ 接收请求 │
│ ├─ 匹配服务 │
│ └─ 转发请求 │
└───────────────────┘
流程图:三大功能协作流程
客户端请求 → 认证中间件 → 限流中间件 → 路由转发 → 后端服务
│ │ │ │
│ 无效Token │ 超过限制 │ 服务不存在 │
│ 返回401 │ 返回429 │ 返回404 │
概念图:三大功能关系
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 客户端请求 │───→│ 认证系统 │───→│ 限流系统 │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
│ ↓
┌─────────────┐ ┌─────────┴────────┐ ┌─────────────┐
│ 服务注册中心│←───│ 路由系统 │───→│ 后端服务 │
└─────────────┘ └──────────────────┘ └─────────────┘
总结:API 网关三大功能是系统的“门卫三兄弟”
- 认证:就像查门票的保安,确保只有合法的用户才能进入系统;
- 限流:就像控制人数的保安,防止活动室被挤爆,保护系统不被过量请求压垮;
- 路由转发:就像地图指引员,帮助用户找到正确的服务,让请求到达目的地。
这三个功能一起工作,让 API 网关成为系统的“智能门卫”,保护系统安全,提高系统可用性,简化服务调用!