ThinkPHP框架长连接高并发之:Think-Worker实战指南 轻松构建高性能PHP应用,性能提升50倍
Think-Worker是一个基于Workerman实现的ThinkPHP扩展,专为构建高性能应用和提升现有应用性能而设计。它通过常驻内存运行模式,避免了传统PHP-FPM每次请求重新加载框架的开销,同时支持HTTP、WebSocket和队列处理,特别适合实时通讯、游戏服务器等场景。本文将带你快速掌握Think-Worker的使用方法,并解答常见问题。
什么是Think-Worker?
Think-Worker是一个ThinkPHP框架的扩展,它利用Workerman的强大功能,为PHP应用提供高性能的运行环境。主要优势包括:
- 高性能长连接 - 基于Workerman实现常驻内存运行,避免传统PHP-FPM每次请求重新加载框架的开销
- 多协议支持 - 同时支持HTTP、WebSocket和队列处理,适合实时通讯、游戏服务器等场景
- 无缝集成ThinkPHP - 完全复用ThinkPHP的路由、中间件、ORM等组件,开发体验一致
- 内置队列处理 - 无需额外进程即可处理队列任务,简化部署和资源管理
第一步:安装和准备
1. 安装扩展
本扩展要求PHP 8.2+和Workerman 5.0+,通过Composer安装:
composer require topthink/think-worker
安装后,会自动在config目录生成worker.php初始配置文件。
2. 启动服务器
php think worker
打开浏览器访问 http://localhost:8080,恭喜你!你的第一个Worker服务器已经运行起来了!
💡 小贴士:如果8080端口被占用,可以在config/worker.php中修改端口号。
第二步:理解基本概念
Worker进程是什么?
传统PHP模式:
用户请求 → 启动PHP进程 → 加载框架 → 处理请求 → 返回结果 → 销毁进程
Worker模式:
启动Worker进程(一直运行) → 用户请求 → 处理请求 → 返回结果 → 等待下一个请求
Worker模式省去了每次请求都要启动进程和加载框架的时间,这就是性能提升的关键!
第三步:HTTP服务器使用
基础配置
编辑config/worker.php:
return [
'http' => [
'enable' => true, // 启用 HTTP 服务器
'host' => '0.0.0.0', // 监听所有 IP
'port' => 8080, // 端口号
'worker_num' => 4, // 进程数(建议设置为 CPU 核心数)
],
// ... 其他配置
];
使用示例
1. 简单的Hello World
在route/app.php中添加:
Route::get('/hello', function () {
return 'Hello, Worker!';
});
2. 处理JSON请求
Route::post('/api/user', function (Request $request) {
$name = $request->post('name');
$age = $request->post('age');
// 处理业务逻辑...
return json([
'code' => 200,
'msg' => '创建成功',
'data' => [
'name' => $name,
'age' => $age,
'id' => rand(1000, 9999)
]
]);
});
3. 文件下载
Route::get('/download/:file', function ($file) {
$path = public_path() . 'downloads/' . $file;
if (!file_exists($path)) {
return '文件不存在';
}
return new \think\worker\response\File($path);
});
4. 服务器推送事件(SSE)
Route::get('/sse/time', function () {
$generator = function () {
while (true) {
yield 'data: ' . json_encode([
'time' => date('Y-m-d H:i:s'),
'memory' => memory_get_usage()
]) . "\n\n";
sleep(1); // 每秒推送一次
}
};
return (new \think\worker\response\Iterator($generator()))
->header([
'Content-Type' => 'text/event-stream',
'Cache-Control' => 'no-cache',
]);
});
前端接收:
const eventSource = new EventSource('/sse/time');
eventSource.onmessage = function(event) {
const data = JSON.parse(event.data);
console.log('服务器时间:', data.time);
};
第四步:WebSocket实时通信
1. 启用WebSocket
在config/worker.php中:
'websocket' => [
'enable' => true,
'handler' => \think\worker\websocket\Handler::class,
'ping_interval' => 25000, // 心跳间隔(毫秒)
'ping_timeout' => 60000, // 心跳超时(毫秒)
],
2. 创建聊天室示例
创建控制器app/controller/Chat.php:
<?php
namespace app\controller;
use think\worker\response\Websocket;
use think\worker\Websocket as WS;
use think\worker\websocket\Frame;
class Chat
{
public function index()
{
return (new Websocket())
->onOpen(function (WS $websocket) {
// 新用户进入聊天室
$websocket->join('chat_room');
// 获取连接ID
$userId = $websocket->getSender();
// 通知所有人
$websocket->to('chat_room')->push([
'type' => 'system',
'msg' => "用户{$userId}进入了聊天室",
'time' => date('H:i:s')
]);
})
->onMessage(function (WS $websocket, Frame $frame) {
// 收到消息
$data = json_decode($frame->data, true);
$userId = $websocket->getSender();
// 广播消息给聊天室所有人
$websocket->to('chat_room')->push([
'type' => 'message',
'user' => $userId,
'msg' => $data['msg'],
'time' => date('H:i:s')
]);
})
->onClose(function (WS $websocket) {
// 用户离开
$userId = $websocket->getSender();
$websocket->to('chat_room')->push([
'type' => 'system',
'msg' => "用户{$userId}离开了聊天室",
'time' => date('H:i:s')
]);
});
}
}
路由配置:
Route::get('/chat', 'Chat/index');
3. 前端连接代码
创建一个简单的聊天页面:
<!DOCTYPE html>
<html>
<head>
<title>WebSocket 聊天室</title>
</head>
<body>
<div id="messages"></div>
<input type="text" id="messageInput" placeholder="输入消息...">
<button onclick="sendMessage()">发送</button>
<script>
// 连接 WebSocket
const ws = new WebSocket('ws://localhost:8080/chat');
// 连接成功
ws.onopen = function() {
addMessage('系统', '连接成功!');
};
// 收到消息
ws.onmessage = function(event) {
const data = JSON.parse(event.data);
if (data.type === 'system') {
addMessage('系统', data.msg);
} else {
addMessage(data.user, data.msg);
}
};
// 发送消息
function sendMessage() {
const input = document.getElementById('messageInput');
const msg = input.value;
if (msg) {
ws.send(JSON.stringify({ msg: msg }));
input.value = '';
}
}
// 显示消息
function addMessage(user, msg) {
const div = document.getElementById('messages');
div.innerHTML += `<p><b>${user}:</b> ${msg}</p>`;
div.scrollTop = div.scrollHeight;
}
// 回车发送
document.getElementById('messageInput').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
sendMessage();
}
});
</script>
</body>
</html>
第五步:队列处理
1. 安装队列组件
composer require topthink/think-queue
2. 配置队列
在config/worker.php中:
'queue' => [
'enable' => true,
'workers' => [
// 默认队列
'default' => [
'delay' => 0, // 延迟时间(秒)
'sleep' => 3, // 没有任务时休眠时间(秒)
'tries' => 3, // 失败重试次数
'timeout' => 60, // 任务超时时间(秒)
'worker_num' => 1, // 处理进程数
],
// 邮件队列(处理较慢,多开几个进程)
'email' => [
'worker_num' => 3,
],
// 紧急队列(优先处理)
'urgent' => [
'sleep' => 1, // 休眠时间短,响应更快
'worker_num' => 2,
],
],
],
3. 创建任务类
创建app/job/SendEmail.php:
<?php
namespace app\job;
use think\queue\Job;
class SendEmail
{
/**
* 执行任务
*/
public function fire(Job $job, $data)
{
try {
// 模拟发送邮件
echo "发送邮件给:{$data['email']}\n";
echo "主题:{$data['subject']}\n";
echo "内容:{$data['content']}\n";
// 实际发送邮件的代码...
// Mail::send(...);
// 任务执行成功,删除任务
$job->delete();
} catch (\Exception $e) {
// 任务执行失败
echo "发送失败:" . $e->getMessage() . "\n";
// 检查是否超过重试次数
if ($job->attempts() > 3) {
echo "重试次数过多,放弃任务\n";
$job->delete();
} else {
// 10秒后重试
$job->release(10);
}
}
}
}
4. 投递任务
在控制器或其他地方:
use think\facade\Queue;
// 立即执行
Queue::push('app\job\SendEmail', [
'email' => 'user@example.com',
'subject' => '欢迎注册',
'content' => '感谢您注册我们的网站!'
], 'email');
// 延迟10秒执行
Queue::later(10, 'app\job\SendEmail', [
'email' => 'user@example.com',
'subject' => '注册成功',
'content' => '您的账号已经创建成功!'
], 'email');
第六步:生产环境部署
1. 使用Supervisor管理进程
安装Supervisor:
sudo apt-get install supervisor
创建配置文件/etc/supervisor/conf.d/think-worker.conf:
[program:think-worker]
command=php /path/to/your/project/think worker
directory=/path/to/your/project
autostart=true
autorestart=true
user=www-data
numprocs=1
redirect_stderr=true
stdout_logfile=/var/log/think-worker.log
启动:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start think-worker
2. Nginx反向代理
server {
listen 80;
server_name your-domain.com;
# 静态文件
location ~ \.(jpg|png|gif|js|css|ico|html)$ {
root /path/to/your/project/public;
}
# HTTP 请求
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# WebSocket
location /chat {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Think-Worker的核心优势
性能对比数据
测试项目 | PHP-FPM | think-worker | 性能提升 |
---|---|---|---|
Hello World QPS | 3,000 | 150,000+ | 50倍 |
复杂业务接口 | 200 QPS | 8,000 QPS | 40倍 |
WebSocket连接数 | 不支持 | 100,000+ | - |
内存占用(100并发) | 2GB | 800MB | 节省60% |
数据库查询耗时 | 5ms(含连接) | 1ms(连接池) | 快5倍 |
核心技术优势
1. 智能内存管理 - Sandbox沙盒机制
think-worker使用创新的沙盒机制,每个请求都在独立的应用副本中运行:
// 自动清理机制
- ClearInstances: 清理单例实例
- ResetConfig: 重置配置状态
- ResetEvent: 清理事件监听
- ResetService: 重置服务状态
- ResetModel: 清理模型缓存
- ResetPaginator: 重置分页器
// 自定义清理器
class MyResetter implements ResetterInterface
{
public function handle(App $app, Sandbox $sandbox)
{
// 清理你的自定义状态
MyCache::clear();
MyGlobal::reset();
}
}
2. 进程间通信 - Conduit系统
独特的Conduit系统实现高效的进程间数据共享:
$conduit = app('think.worker.conduit');
// 原子操作
$conduit->inc('counter'); // 原子递增
$conduit->set('key', 'value'); // 设置值
$conduit->get('key'); // 获取值
// 集合操作
$conduit->sAdd('online_users', $userId);
$conduit->sMembers('online_users');
// 发布订阅
$conduit->publish('channel', $message);
$conduit->subscribe('channel', function($message) {
// 处理消息
});
// 实现分布式锁
if ($conduit->inc('lock:resource') === 1) {
try {
// 执行临界区代码
} finally {
$conduit->set('lock:resource', 0);
}
}
3. FlexHttp协议 - 一端口多协议
同一端口同时支持HTTP和WebSocket:
// 自动识别协议,无需额外配置
// HTTP: http://localhost:8080/api
// WebSocket: ws://localhost:8080/chat
总结
恭喜你!现在你已经掌握了think-worker的核心功能:
✅ HTTP高性能服务器
✅ WebSocket实时通信
✅ 队列异步处理
✅ 生产环境部署
相比传统PHP-FPM,think-worker能让你的应用:
- 响应速度提升10-100倍
- 支持长连接和实时推送
- 更高效地处理并发请求
- 更好地利用服务器资源
记住:think-worker不是魔法,而是一种更高效的运行方式。它特别适合:
- 需要实时通信的应用(聊天、游戏、协作)
- 高并发的API服务
- 需要推送通知的系统
- IoT物联网应用
虽然think-worker原生不支持分布式,但通过本教程提供的方案,你可以轻松扩展到多服务器部署。选择合适的方案,让你的应用飞起来!
版权声明:本文为原创文章,版权归 全栈开发技术博客 所有。
本文链接:https://www.lvtao.net/dev/think-worker-quick-guide-and-faq.html
转载时须注明出处及本声明
- 上一篇: ThinkPHP框架中数据库操作之:ThinkORM 大数据处理全攻略:告别内存溢出,轻松应对海量数据
- 下一篇: 没有了