Announcement

👇Official Account👇

Welcome to join the group & private message

Article first/tail QR code

Skip to content

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 Fiberstable标准库通用逻辑编排
Swoole 6.06.0.3极高丰富高性能服务
OpenSwoole 6.x6.0极高Swoole 替代C 扩展受限环境
FrankenPHP 1.41.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)

方案QPSP99 延迟错误率
PHP-FPM + Nginx1,200850ms0%
Swoole 6.098,00012ms0.02%
FrankenPHP 1.432,00035ms0.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 属性 → 本篇

上次更新于: