【swoole】OpenSwoole的应用

小破孩
2026-03-27 / 0 评论 / 2 阅读 / 正在检测是否收录...

OpenSwoole 是 PHP 的异步、协程、高性能网络通信引擎,能让 PHP 做到:

  • 高性能 HTTP 服务(替代 Nginx+FPM,单机万级并发)
  • 异步任务(邮件、短信、推送不阻塞主流程)
  • 定时任务(替代 Linux Crontab)
  • WebSocket 实时通信(聊天室、实时通知)
  • TCP/UDP 服务、微服务、高并发爬虫

环境准备(1 分钟安装)

# 安装 openswoole 扩展
pecl install openswoole

验证:

<?php
echo OpenSwoole\Util::getVersion();

场景 1:搭建高性能 HTTP 服务(最常用)

替代传统 Nginx+PHP-FPM,并发提升 10~100 倍,支持路由、静态文件、接口服务。

完整可运行代码

<?php
use OpenSwoole\Http\Server;
use OpenSwoole\Http\Request;
use OpenSwoole\Http\Response;

// 创建 HTTP 服务,监听 0.0.0.0:9501
$server = new Server('0.0.0.0', 9501);

// 配置(worker 数 = CPU 核心数)
$server->set([
    'worker_num' => 4,
    'enable_static_handler' => true,
    'document_root' => __DIR__ . '/public', // 静态文件目录
]);

// 处理请求
$server->on('Request', function (Request $request, Response $response) {
    // 获取请求参数
    $path = $request->server['request_uri'];
    $get = $request->get;
    $post = $request->post;

    // 路由分发
    if ($path === '/') {
        $response->header('Content-Type', 'text/html; charset=utf-8');
        $response->end("<h1>OpenSwoole HTTP 服务运行中</h1>");
    } 
    // 接口示例:用户信息
    elseif ($path === '/api/user') {
        $uid = $get['uid'] ?? 0;
        $response->header('Content-Type', 'application/json');
        $response->end(json_encode([
            'code' => 0,
            'msg' => 'success',
            'data' => [
                'uid' => $uid,
                'name' => 'OpenSwoole 用户',
                'time' => date('Y-m-d H:i:s')
            ]
        ]));
    } 
    else {
        $response->status(404);
        $response->end("404 Not Found");
    }
});

echo "服务启动:http://127.0.0.1:9501\n";
$server->start();

运行 & 测试

php http_server.php
# 访问
# http://127.0.0.1:9501
# http://127.0.0.1:9501/api/user?uid=100

你必须掌握的点

  • Request 封装所有请求信息(GET/POST/HEADER/COOKIE)
  • Response 只能调用一次 end(),响应结束
  • 服务常驻内存,比传统 PHP 快极多

场景 2:异步任务(最核心业务价值)

场景:注册发送邮件、下单发送短信、日志上报、数据统计——不阻塞用户请求

异步任务服务器代码

<?php
use OpenSwoole\Http\Server;
use OpenSwoole\Http\Request;
use OpenSwoole\Http\Response;

$server = new Server('0.0.0.0', 9502);
$server->set([
    'worker_num' => 2,
    'task_worker_num' => 4, // 任务进程数
]);

// 处理 HTTP 请求
$server->on('Request', function (Request $request, Response $response) use ($server) {
    // 业务:用户注册
    $data = [
        'email' => 'test@demo.com',
        'content' => '欢迎注册'
    ];
    
    // 投递异步任务(非阻塞,瞬间返回)
    $server->task($data);
    
    // 直接响应,不用等邮件发送完成
    $response->end("注册成功,邮件已发送");
});

// 任务处理进程
$server->on('Task', function ($server, $taskId, $workerId, $data) {
    echo "开始发送邮件:{$data['email']}\n";
    // 模拟耗时:2 秒(真实场景:发送邮件/短信/推送)
    sleep(2);
    echo "邮件发送完成\n";
    
    // 任务完成
    return 'success';
});

// 任务完成回调
$server->on('Finish', function ($server, $taskId, $result) {
    echo "任务 $taskId 完成,结果:$result\n";
});

$server->start();

核心价值

  • 用户请求0 等待
  • 耗时任务丢给任务进程,不影响接口响应速度
  • 支撑高并发业务必备

场景 3:WebSocket 实时通信(聊天室/实时通知)

场景:在线客服、实时弹幕、订单状态实时推送、游戏。

服务端代码

<?php
use OpenSwoole\WebSocket\Server;
use OpenSwoole\WebSocket\Frame;
use OpenSwoole\Http\Request;

$server = new Server('0.0.0.0', 9503);

// 客户端连接
$server->on('Open', function (Server $server, Request $request) {
    echo "客户端 {$request->fd} 连接\n";
});

// 接收消息并广播
$server->on('Message', function (Server $server, Frame $frame) {
    echo "收到消息:{$frame->data}\n";
    
    // 广播给所有在线客户端(聊天室核心)
    foreach ($server->connections as $fd) {
        if ($server->isEstablished($fd)) {
            $server->push($fd, "广播:{$frame->data}");
        }
    }
});

// 客户端关闭
$server->on('Close', function (Server $server, $fd) {
    echo "客户端 {$fd} 断开\n";
});

$server->start();

前端测试代码(HTML)

<script>
const ws = new WebSocket('ws://127.0.0.1:9503');
ws.onmessage = (e) => alert(e.data);
// 发送消息
ws.send('Hello OpenSwoole');
</script>

场景 4:定时任务(替代 Crontab,更灵活)

场景:每分钟统计订单、每小时清理缓存、每天同步数据。

<?php
use OpenSwoole\Timer;

// 每 1 秒执行
Timer::tick(1000, function () {
    echo "每秒执行:" . date('H:i:s') . "\n";
});

// 5 秒后执行一次
Timer::after(5000, function () {
    echo "5 秒后执行\n";
});

// 保持服务运行
Swoole\Event::wait();

场景 5:协程 MySQL + Redis(高并发数据库操作)

OpenSwoole 协程能让IO 操作(MySQL/Redis/Curl)并发执行,速度提升巨大。

协程 MySQL 示例

<?php
use OpenSwoole\Coroutine\MySQL;
use OpenSwoole\Coroutine;

Coroutine::create(function () {
    $db = new MySQL();
    $db->connect([
        'host' => '127.0.0.1',
        'user' => 'root',
        'password' => '123456',
        'database' => 'test',
    ]);
    
    $res = $db->query('SELECT * FROM user LIMIT 1');
    var_dump($res);
});

并发请求(3 个请求并行,只花 1 秒而不是 3 秒)

<?php
use OpenSwoole\Coroutine;

Coroutine\run(function () {
    // 并行 3 个协程
    Coroutine::create(function () { sleep(1); echo "任务1\n"; });
    Coroutine::create(function () { sleep(1); echo "任务2\n"; });
    Coroutine::create(function () { sleep(1); echo "任务3\n"; });
});

场景 6:多进程处理(大量数据导出/批量任务)

场景:百万数据导出、批量发送消息、数据清洗。

<?php
use OpenSwoole\Process;

// 创建 4 个子进程
for ($i = 0; $i < 4; $i++) {
    $process = new Process(function () use ($i) {
        echo "子进程 $i 运行,PID:" . getmypid() . "\n";
        sleep(2);
        echo "子进程 $i 结束\n";
    });
    $process->start();
}

// 回收子进程
while ($ret = Process::wait()) {
    echo "子进程 {$ret['pid']} 退出\n";
}

你必须掌握的 5 个核心特性(精通关键)

1. 常驻内存

  • 传统 PHP:请求结束 → 销毁所有变量
  • OpenSwoole:变量常驻内存,重复使用
  • 注意:不要用全局变量存用户会话,会串请求

2. 协程(Coroutine)

  • 轻量级线程,开销极小
  • IO 阻塞(MySQL/Redis/Curl)自动切换
  • 高并发核心技术

3. 异步非阻塞

  • 任务、消息推送、文件IO都可以异步
  • 接口响应速度极快

4. 多进程模型

  • Master 管理进程
  • Worker 处理请求
  • Task 处理异步任务

5. 热重启(生产必备)

修改代码后不用重启服务:

kill -USR1 主进程PID

生产环境最佳实践(直接照做)

  1. 配置 worker_num = CPU 核心数
  2. 静态文件用 Nginx 代理,PHP 接口用 OpenSwoole
  3. 数据库连接使用连接池
  4. 定时任务统一管理
  5. 使用 systemd 守护进程

总结

你现在已经掌握 OpenSwoole 最实用的 6 大业务场景,所有代码复制即可运行

  1. HTTP 高性能接口服务
  2. 异步任务(邮件/短信/推送)
  3. WebSocket 实时通信
  4. 定时任务
  5. 协程并发 MySQL/Redis
  6. 多进程批量任务
0

评论 (0)

取消