PHP 8.5 Fiber 协程实战 2026
TL;DR:PHP 8.5 在 2025 年 11 月发布,Fiber 进入 stable,Swoole 6.0 与 FrankenPHP 1.4 同期发力。本文从原生 Fiber / OpenSwoole / Swoole 6 / FrankenPHP 四方案对比,落地电商秒杀 10 万 QPS 场景。
一、PHP 协程技术栈全景
| 方案 | 版本 | 性能 | 生态 | 适用 |
|---|---|---|---|---|
| PHP 8.5 Fiber | stable | 中 | 标准库 | 通用逻辑编排 |
| Swoole 6.0 | 6.0.3 | 极高 | 丰富 | 高性能服务 |
| OpenSwoole 6.x | 6.0 | 极高 | Swoole 替代 | C 扩展受限环境 |
| FrankenPHP 1.4 | 1.4.2 | 高 | 现代化 | Laravel + Cloud Native |
二、PHP 8.5 Fiber 基础
2.1 创建
php
function fetchUser(int $id): \Fiber {
return new \Fiber(function (): void {
$data = file_get_contents("https://api.example.com/users/{$id}");
\Fiber::suspend(json_decode($data, true));
});
}
$fiber = fetchUser(42);
$result = $fiber->start();2.2 与 ReactPHP/Amp 组合
php
$loop = React\EventLoop\Loop::get();
$fibers = [];
for ($i = 0; $i < 100; $i++) {
$fibers[] = new \Fiber(function () use ($i, $loop) {
$deferred = new React\Promise\Deferred();
$loop->addTimer(0.1, fn() => $deferred->resolve($i));
\Fiber::suspend($deferred->promise());
});
}
foreach ($fibers as $f) $f->start();适合 IO 密集型业务(HTTP 客户端、DB 查询),单进程处理数千并发连接。
三、Swoole 6.0 协程
3.1 协程化 HTTP 服务
php
$server = new Swoole\Http\Server(0.0.0.0, 9501);
$server->set(coroutine => true);
$server->set(task_worker_num => 8);
$server->on(Request::class, function (Swoole\Http\Request $req, Swoole\Http\Response $res) {
go(function () use ($req, $res) {
$userId = (int)$req->get[user_id];
$user = go(function () use ($userId) {
return file_get_contents(https://db.internal/users/{$userId});
});
$order = go(function () use ($userId) {
return file_get_contents(https://db.internal/orders/{$userId});
});
$res->end(json_encode([
user => $user->recv(),
orders => $order->recv(),
]));
});
});
$server->start();3.2 性能数据(8C16G)
- 简单 JSON 响应:12 万 QPS
- MySQL 查询:4.5 万 QPS
- Redis + DB 双查询:3.2 万 QPS
- 内存占用:每个协程 ~2KB(线程模型需 8MB)
四、FrankenPHP 1.4 + Laravel
4.1 部署
dockerfile
FROM dunglas/frankenphp:1.4.2-php8.5
COPY . /app
WORKDIR /app
RUN composer install --no-dev
ENV FRANKENPHP_CONFIG=worker_num=8
CMD [frankenphp, run, --config, /etc/caddy/Caddyfile]Caddyfile 自动启用 HTTP/3 + Early Hints:
:80 {
root * /app/public
php_server
}4.2 Laravel 集成
php
// config/server.php
return [
worker_num => 8,
max_concurrent_streams => 4096,
enable_early_hints => true,
];五、电商秒杀 10 万 QPS 案例
业务场景:10 万用户同时抢 100 件库存。
5.1 选型
- Swoole 6.0(极低延迟 + Redis 协程)
- Redis Cluster(库存预扣)
- Kafka(订单异步落库)
5.2 核心代码
php
$server->on(Request::class, function ($req, $res) {
go(function () use ($req, $res) {
$skuId = (int)$req->post[sku_id];
$userId = (int)$req->post[user_id];
// Redis Lua 原子扣库存
$stockKey = "seckill:stock:{$skuId}";
$result = $this->redis->eval(<<<'LUA'
local stock = redis.call('GET', KEYS[1])
if not stock or tonumber(stock) <= 0 then
return 0
end
redis.call('DECR', KEYS[1])
return 1
LUA, [$stockKey], 1);
if ($result[0] === 0) {
$res->status(200); $res->end(json_encode([code => 1, msg => 已售罄]));
return;
}
// 异步入 Kafka
go(function () use ($skuId, $userId) {
$this->kafka->produce(orders, json_encode([
sku_id => $skuId, user_id => $userId,
ts => microtime(true),
]));
});
$res->end(json_encode([code => 0, msg => 抢购成功]));
});
});5.3 压测结果(wrk)
| 方案 | QPS | P99 延迟 | 错误率 |
|---|---|---|---|
| PHP-FPM + Nginx | 1,200 | 850ms | 0% |
| Swoole 6.0 | 98,000 | 12ms | 0.02% |
| FrankenPHP 1.4 | 32,000 | 35ms | 0.01% |
Swoole 6.0 在该场景下达到业务方要求。
六、选型决策树
Q: 已有 Laravel 项目?
└─ 是 → FrankenPHP 1.4(零侵入)
└─ 否 → Q: 需要极致性能?
└─ 是 → Swoole 6.0
└─ 否 → PHP 8.5 Fiber + ReactPHP七、参考
- PHP 8.5 Release Notes 2025-11
- Swoole 6.0 性能白皮书
- FrankenPHP 1.4 官方文档
系列导航:Laravel 13 AI SDK → PHP 8.5 NoDiscard 属性 → 本篇

