发布日期:2024年3月20日
一、系统架构设计
本教程将实现一个完整的API网关系统,主要解决以下核心问题:
- 动态路由配置:无需重启的热更新
- 智能限流:自适应流量控制
- 统一鉴权:JWT与OAuth2.0集成
- 协议转换:REST/gRPC/GraphQL互转
- 监控告警:Prometheus指标采集
技术栈:ThinkPHP8.1 + Swoole + Redis + Nacos + Prometheus
二、环境准备与项目初始化
1. 创建ThinkPHP项目
composer create-project topthink/think api-gateway
cd api-gateway
composer require predis/predis swoole/ide-helper nacos/php-sdk
2. 目录结构规划
app/
├── controller/ # 控制器
├── gateway/ # 网关核心
│ ├── filter/ # 过滤器
│ ├── router/ # 路由解析
│ └── service/ # 网关服务
├── middleware/ # 中间件
├── model/ # 数据模型
config/
├── gateway.php # 网关配置
├── route.php # 路由配置
extend/
├── prometheus/ # 监控组件
public/
├── metrics # 指标端点
runtime/
├── gateway/ # 运行时缓存
三、核心功能实现
1. 动态路由配置
// app/gateway/router/DynamicRouter.php
class DynamicRouter
{
protected $routes = [];
public function loadFromNacos()
{
$nacos = new NacosClient();
$config = $nacos->getConfig('gateway_routes');
$this->routes = json_decode($config, true);
}
public function dispatch($request)
{
$path = $request->path();
$method = $request->method();
foreach ($this->routes as $route) {
if ($this->matchRoute($route, $path, $method)) {
return $this->createResponse($route);
}
}
throw new RouteNotFoundException();
}
protected function matchRoute($route, $path, $method)
{
// 实现路径匹配逻辑
}
}
2. 智能限流中间件
// app/middleware/RateLimit.php
class RateLimit
{
public function handle($request, Closure $next)
{
$route = $request->route();
$clientIp = $request->ip();
$limiter = new TokenBucket(
$route->getRate(),
$route->getBurst()
);
if (!$limiter->consume(1, $clientIp)) {
return json([
'code' => 429,
'msg' => '请求过于频繁'
]);
}
return $next($request);
}
}
// TokenBucket算法实现
class TokenBucket
{
public function consume($tokens, $key)
{
$redis = new Redis();
$now = microtime(true);
$rate = $this->rate / $this->capacity;
$lastTime = $redis->hGet($key, 'last_time') ?: $now;
$tokensLeft = $redis->hGet($key, 'tokens') ?: $this->capacity;
$tokensLeft = min(
$this->capacity,
$tokensLeft + ($now - $lastTime) * $rate
);
if ($tokensLeft hMSet($key, [
'last_time' => $now,
'tokens' => $tokensLeft - $tokens
]);
return true;
}
}
四、统一鉴权系统
1. JWT认证服务
// app/gateway/service/AuthService.php
class AuthService
{
public function authenticate($token)
{
try {
$payload = JWT::decode($token, config('jwt.key'));
return [
'uid' => $payload->uid,
'roles' => $payload->roles,
'exp' => $payload->exp
];
} catch (Exception $e) {
throw new AuthFailedException();
}
}
public function generateToken($user)
{
$payload = [
'iss' => config('app.app_host'),
'uid' => $user['id'],
'roles' => $user['roles'],
'iat' => time(),
'exp' => time() + 3600
];
return JWT::encode($payload, config('jwt.key'));
}
}
2. 权限校验过滤器
// app/gateway/filter/AclFilter.php
class AclFilter
{
public function check($request, $route)
{
$authHeader = $request->header('Authorization');
$token = str_replace('Bearer ', '', $authHeader);
$auth = app(AuthService::class)->authenticate($token);
$requiredRoles = $route->getMetadata('roles', []);
if (!array_intersect($requiredRoles, $auth['roles'])) {
throw new ForbiddenException();
}
$request->user = $auth;
}
}
五、协议转换引擎
1. REST转gRPC适配器
// app/gateway/service/GrpcAdapter.php
class GrpcAdapter
{
public function transform($restRequest, $serviceConfig)
{
$grpcClient = new GrpcClient($serviceConfig['host']);
$request = new $serviceConfig['request_class']();
foreach ($serviceConfig['field_map'] as $rest => $grpc) {
$setter = 'set' . ucfirst($grpc);
$request->$setter($restRequest->param($rest));
}
list($response, $status) = $grpcClient->{$serviceConfig['method']}(
$request,
['timeout' => 3000]
)->wait();
return $this->formatResponse($response);
}
}
2. 响应统一格式化
// app/gateway/service/ResponseFormatter.php
class ResponseFormatter
{
public function format($raw, $type)
{
switch ($type) {
case 'json':
return $this->formatJson($raw);
case 'grpc':
return $this->formatGrpc($raw);
case 'graphql':
return $this->formatGraphQL($raw);
default:
return $raw;
}
}
protected function formatGrpc($response)
{
$result = [];
foreach ($response->getFieldList() as $field) {
$getter = 'get' . ucfirst($field);
$result[$field] = $response->$getter();
}
return json($result);
}
}
六、监控告警系统
1. Prometheus指标收集
// extend/prometheus/Metrics.php
class Metrics
{
protected static $registry;
public static function init()
{
self::$registry = new CollectorRegistry();
self::$registry->registerGauge(
'api_requests_total',
'Total API requests',
['method', 'path', 'status']
);
self::$registry->registerHistogram(
'api_response_time',
'API response time',
['method', 'path'],
[0.1, 0.5, 1, 2.5, 5]
);
}
public static function observe($metric, $value, $labels = [])
{
self::$registry->getOrRegisterMetric($metric)
->observe($value, $labels);
}
}
// 在中间件中记录指标
Metrics::observe('api_requests_total', 1, [
$request->method(),
$request->path(),
$response->getCode()
]);
2. 告警规则配置
# prometheus/rules/api_gateway.rules.yml
groups:
- name: api_gateway
rules:
- alert: HighErrorRate
expr: rate(api_requests_total{status=~"5.."}[1m]) > 0.1
for: 5m
labels:
severity: critical
annotations:
summary: "High error rate on {{ $labels.path }}"
description: "Error rate is {{ $value }}"
- alert: SlowAPI
expr: histogram_quantile(0.9, rate(api_response_time_bucket[1m])) > 2
for: 10m
labels:
severity: warning
七、性能优化方案
1. Swoole协程优化
// config/swoole.php
return [
'host' => '0.0.0.0',
'port' => 9501,
'mode' => SWOOLE_PROCESS,
'sock_type' => SWOOLE_SOCK_TCP,
'options' => [
'worker_num' => swoole_cpu_num() * 2,
'enable_coroutine' => true,
'task_worker_num' => 4,
'max_request' => 10000,
]
];
// 协程MySQL客户端
Corun(function() {
$mysql = new SwooleCoroutineMySQL();
$mysql->connect([
'host' => '127.0.0.1',
'user' => 'root',
'password' => '',
'database' => 'test'
]);
$result = $mysql->query('SELECT * FROM users');
});
2. 路由缓存预热
// app/command/RouteCache
class RouteCache extends Command
{
protected function configure()
{
$this->setName('route:cache');
}
protected function execute(Input $input, Output $output)
{
$router = app(Route::class);
$routes = $router->getRouteList();
$cache = [];
foreach ($routes as $route) {
$cache[$route->getRule()] = [
'path' => $route->getRoute(),
'method' => $route->getMethod(),
'option' => $route->getOption()
];
}
file_put_contents(
runtime_path('gateway/route.cache'),
serialize($cache)
);
}
}
八、总结与扩展
通过本教程,您已经掌握了:
- API网关的核心架构设计
- ThinkPHP8的高阶应用
- 微服务通信协议转换
- 高并发场景下的性能优化
扩展学习方向:
- 服务网格(Service Mesh)集成
- 全链路灰度发布
- API编排引擎
- Wasm插件系统