Workerman 常驻内存编程

定位

Workerman 是纯 PHP 的常驻内存网络库,不是框架。它提供事件循环、TCP/UDP/WebSocket 服务端、定时器、进程管理。

它的定位是「让 PHP 能做长连接和常驻进程」,而不是「替代 Laravel」。

安装

composer require workerman/workerman

要求 PHP CLI 环境,不需要额外扩展(不像 Swoole 需要编译安装)。

最小示例

一个 HTTP 服务

<?php
// http_server.php
require_once __DIR__ . '/vendor/autoload.php';

use WorkermanWorker;

$http = new Worker('http://0.0.0.0:8080');

$http->onMessage = function ($connection, $request) {
    $connection->send("Hello, {$request->get('name', 'world')}");
};

Worker::runAll();
php http_server.php start      # 前台运行
php http_server.php start -d   # 后台守护
php http_server.php stop
php http_server.php status

一个 WebSocket 服务

<?php
use WorkermanWorker;

$ws = new Worker('websocket://0.0.0.0:8282');
$ws->count = 4;                        // 开 4 个进程

// 保存所有连接
$connections = [];

$ws->onConnect = function ($conn) use (&$connections) {
    $connections[$conn->id] = $conn;
};

$ws->onMessage = function ($conn, $data) use (&$connections) {
    // 广播给所有人
    foreach ($connections as $c) {
        $c->send("someone said: {$data}");
    }
};

$ws->onClose = function ($conn) use (&$connections) {
    unset($connections[$conn->id]);
};

Worker::runAll();

核心概念

1. 事件循环 + 回调

Workerman 的核心是 EventLoop(底层用 epoll / select)。你注册回调,它负责在事件发生时调用:

$worker->onConnect    = fn($conn) => ...;   // 连接建立
$worker->onMessage    = fn($conn, $data) => ...;  // 收到数据
$worker->onClose      = fn($conn) => ...;   // 连接关闭
$worker->onError      = fn($conn, $code, $msg) => ...;

2. 多进程模型

$worker->count = 4 会 fork 出 4 个子进程,每个进程独立处理连接。进程之间不共享内存,要通信得用 Redis、共享内存或 Workerman 自带的 channel 组件。

这是和 Swoole 的主要差异之一:Swoole 有协程和更丰富的进程间通信。

3. 定时器

use WorkermanTimer;

// 每 2 秒执行一次
Timer::add(2, function () {
    echo "tickn";
});

// 只执行一次
Timer::add(5, fn() => echo "oncen", [], false);

常驻进程里的定时任务比 crontab 更精确、开销更低。这是 Workerman 一个被低估的用途。

常见坑

① 进程数不是越多越好

count 设成 CPU 核数的 1-4 倍即可。设太大会增加进程切换开销。而且每个进程独立占内存,PHP 的常驻内存不小。

② 全局变量不跨进程

$count = 0;
$worker->count = 4;
$worker->onMessage = function ($conn) use (&$count) {
    $count++;    // 每个进程各算各的,总数对不上
};

要统计全局数据,用 Redis 的 INCR。

③ 内存只增不减

常驻进程跑久了内存上涨,通常是:连接对象没清理、数组只 add 不 unset、闭包捕获了大对象。要么定期重启(php start.php restart 配合定时任务),要么严格管理内存。

④ 不能直接跑 Laravel/ThinkPHP

Workerman 是库不是框架。要用框架的路由、ORM,得自己桥接(或者用现成的 Webman)。

什么时候选它

  • 需要 WebSocket、TCP 长连接、MQTT、物联网接入
  • 需要自定义协议(二进制协议、心跳、私有协议)
  • 需要高频定时任务
  • 想给现有项目加一个常驻进程,不想引入整个框架

不选它的场景:普通 HTTP API(用 FPM 或框架)、需要框架生态(用 Webman)、需要协程(用 Swoole/Hyperf)。

一个实际用途:替代 crontab

很多场景下 Workerman 的定时器比系统 crontab 更合适:

$worker = new Worker();
$worker->count = 1;

// 每秒检查一次队列,比 crontab 的分钟级精度高
Timer::add(1, function () {
    // 消费队列
});

Worker::runAll();

优势:精度高(毫秒级)、不用起进程(复用常驻进程)、能看到实时日志。 代价:进程挂了任务就停,需要配合进程守护(start -d 自带守护,或交给 systemd)。

暂无评论

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇