本文目录导读:

我来给你一套PHP开发API网关的完整思路,从架构设计到具体实现。
核心架构设计
整体架构
客户端 → API网关 → 微服务集群
↓
认证/限流/路由/日志
目录结构
api-gateway/
├── public/
│ └── index.php # 入口文件
├── src/
│ ├── Core/
│ │ ├── Router.php # 路由分发
│ │ ├── Handler.php # 处理器链
│ │ └── Response.php # 响应处理
│ ├── Middleware/
│ │ ├── Auth.php # 认证中间件
│ │ ├── RateLimit.php # 限流中间件
│ │ ├── Logger.php # 日志中间件
│ │ └── CORS.php # 跨域处理
│ ├── Service/
│ │ ├── Proxy.php # 服务转发
│ │ ├── LoadBalancer.php # 负载均衡
│ │ └── CircuitBreaker.php # 熔断器
│ └── Config/
│ └── routes.php # 路由配置
└── composer.json
核心实现代码
入口文件
<?php // public/index.php require __DIR__ . '/../vendor/autoload.php'; use Gateway\Core\Router; use Gateway\Core\Handler; // 初始化配置 $config = require __DIR__ . '/../src/Config/routes.php'; // 创建路由 $router = new Router($config); // 创建处理器链 $handler = new Handler($router); $handler->addMiddleware(new \Gateway\Middleware\CORS()); $handler->addMiddleware(new \Gateway\Middleware\Logger()); $handler->addMiddleware(new \Gateway\Middleware\Auth()); $handler->addMiddleware(new \Gateway\Middleware\RateLimit()); // 处理请求 $handler->handle();
路由核心
<?php
namespace Gateway\Core;
class Router {
private $routes = [];
private $services = [];
public function __construct($config) {
$this->routes = $config['routes'] ?? [];
$this->services = $config['services'] ?? [];
}
public function route() {
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$method = $_SERVER['REQUEST_METHOD'];
foreach ($this->routes as $pattern => $route) {
if ($this->match($pattern, $path, $matches)) {
return [
'service' => $route['service'],
'path' => $this->buildTargetPath($route, $matches),
'method' => $method
];
}
}
return null;
}
private function match($pattern, $path, &$matches) {
$pattern = preg_replace('/\{[^\/]+\}/', '([^\/]+)', $pattern);
$pattern = str_replace('/', '\/', $pattern);
return preg_match("/^{$pattern}$/", $path, $matches);
}
private function buildTargetPath($route, $matches) {
$path = $route['path'] ?? '';
array_shift($matches);
foreach ($matches as $value) {
$path = preg_replace('/\{[^\/]+\}/', $value, $path, 1);
}
return $path;
}
}
处理器链
<?php
namespace Gateway\Core;
class Handler {
private $middleware = [];
private $router;
public function __construct($router) {
$this->router = $router;
}
public function addMiddleware($middleware) {
$this->middleware[] = $middleware;
return $this;
}
public function handle() {
// 创建请求对象
$request = new Request();
$response = new Response();
// 创建处理链
$next = function() use ($response) {
return $response;
};
// 反向遍历中间件
$middlewares = array_reverse($this->middleware);
foreach ($middlewares as $middleware) {
$next = function() use ($middleware, $request, $next) {
return $middleware->process($request, $next);
};
}
// 执行处理链
$result = $next();
// 输出响应
$result->send();
}
}
服务转发(代理)
<?php
namespace Gateway\Service;
class Proxy {
private $httpClient;
public function forward($request, $targetService) {
$url = $this->buildUrl($targetService, $request->getPath());
$options = [
'http' => [
'method' => $request->getMethod(),
'header' => $this->buildHeaders($request),
'content' => $request->getContent(),
'timeout' => 5,
'ignore_errors' => true
]
];
// 使用多线程处理并发请求
return $this->asyncRequest($url, $options);
}
private function buildUrl($service, $path) {
// 结合负载均衡策略选择实例
$instance = LoadBalancer::select($service);
return "http://{$instance['host']}:{$instance['port']}{$path}";
}
private function asyncRequest($url, $options) {
$shared = [];
$client = curl_init();
curl_setopt_array($client, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_FOLLOWLOCATION => true,
]);
// 使用Swoole或ReactPHP实现真正的异步
return $this->executeAsync($client);
}
}
认证中间件
<?php
namespace Gateway\Middleware;
use Firebase\JWT\JWT;
class Auth {
private $jwtSecret = 'your-secret-key';
public function process($request, $next) {
// 获取token
$token = $this->extractToken($request);
if (!$token) {
return new \Gateway\Core\Response(401, ['error' => 'Unauthorized']);
}
// 验证JWT
try {
$payload = JWT::decode($token, $this->jwtSecret, ['HS256']);
$request->setUser($payload->user);
} catch (\Exception $e) {
return new \Gateway\Core\Response(401, ['error' => 'Token invalid']);
}
// 权限检查
$route = $request->getRoute();
if (!$this->checkPermission($payload->user, $route)) {
return new \Gateway\Core\Response(403, ['error' => 'Forbidden']);
}
// 传递给下一个中间件
return $next($request);
}
}
限流中间件
<?php
namespace Gateway\Middleware;
use Predis\Client;
class RateLimit {
private $redis;
private $limit = 60; // 每分钟请求数
private $window = 60; // 窗口时间(秒)
public function __construct() {
$this->redis = new Client([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
]);
}
public function process($request, $next) {
$ip = $request->getClientIp();
$key = "rate_limit:{$ip}";
// 滑动窗口限流
$current = $this->redis->incr($key);
if ($current === 1) {
$this->redis->expire($key, $this->window);
}
if ($current > $this->limit) {
return new \Gateway\Core\Response(429, [
'error' => 'Too Many Requests'
]);
}
return $next($request);
}
}
熔断器
<?php
namespace Gateway\Service;
class CircuitBreaker {
private $failureCount = 0;
private $successCount = 0;
private $threshold = 5;
private $timeout = 30;
private $state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN
public function call($callback) {
if ($this->state === 'OPEN') {
if (time() > $this->lastOpenTime + $this->timeout) {
$this->state = 'HALF_OPEN';
} else {
return $this->fallback();
}
}
try {
$result = $callback();
$this->onSuccess();
return $result;
} catch (\Exception $e) {
$this->onFailure();
return $this->fallback();
}
}
}
配置中心
<?php
// src/Config/routes.php
return [
'routes' => [
'/user/\{id\}' => [
'service' => 'user-service',
'path' => '/users/{id}',
'auth' => true,
'permission' => 'user.view'
],
'/order/\{id\}' => [
'service' => 'order-service',
'path' => '/orders/{id}'
]
],
'services' => [
'user-service' => [
'instances' => [
['host' => '192.168.1.1', 'port' => 8080],
['host' => '192.168.1.2', 'port' => 8080]
],
'load_balance' => 'round_robin'
],
'order-service' => [
'instances' => [
['host' => '192.168.2.1', 'port' => 8081]
]
]
]
];
高级特性
使用Swoole实现高性能
// swoole_server.php
use Swoole\Http\Server;
use Swoole\Http\Request;
use Swoole\Http\Response;
$server = new Server("0.0.0.0", 9501);
$server->on("start", function ($server) {
echo "Gateway started\n";
});
$server->on("request", function (Request $request, Response $response) {
// 处理请求
$handler = new Gateway\Core\Handler(new Router($config));
$result = $handler->handleAsync($request);
$response->header("Content-Type", "application/json");
$response->end(json_encode($result));
});
$server->start();
使用Redis做服务发现
<?php
namespace Gateway\Service;
class ServiceDiscovery {
private $redis;
public function __construct() {
$this->redis = new Redis();
$this->redis->connect('127.0.0.1', 6379);
}
public function getServiceInstances($serviceName) {
// 服务注册表
$key = "service:{$serviceName}";
return $this->redis->hgetall($key);
}
public function register() {
// 注册当前服务
}
}
部署与运维
Docker部署
# docker-compose.yml
version: '3'
services:
api-gateway:
build: .
ports:
- "80:80"
environment:
- REDIS_HOST=redis
- DB_HOST=mysql
depends_on:
- redis
- mysql
redis:
image: redis:alpine
ports:
- "6379:6379"
mysql:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=secret
监控指标
<?php
// 添加统计中间件
class StatisticsMiddleware {
public function process($request, $next) {
$start = microtime(true);
$response = $next($request);
$duration = microtime(true) - $start;
// 记录指标
Metrics::record([
'path' => $request->getPath(),
'duration' => $duration,
'status' => $response->getStatus(),
'timestamp' => time()
]);
return $response;
}
}
这套架构已经涵盖API网关的核心功能,你可以根据业务需求选择相应的组件和实现方式,推荐使用Swoole或ReactPHP来提升并发处理能力。