视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
workerman如何实现异步任务(附代码)
2020-11-03 23:08:57 责编:小采
文档

1、问题

遇到一个问题,php是单线程,无法实现多线程。现在我需要使用一个场景是多个链接使用一个线程,也就是在一个连接进程,再开进程来处理

2、解决方案

workerman如何实现异步任务。workerman可以帮我解决问题, 给予文档一个解答

问:

如何异步处理繁重的业务,避免主业务被长时间阻塞。例如我要给1000用户发送邮件,这个过程很慢,可能要阻塞数秒,这个过程中因为主流程被阻塞,会影响后续的请求,如何将这样的繁重任务交给其它进程异步处理。

答:

可以在本机或者其它服务器甚至服务器集群预先建立一些任务进程处理繁重的业务,任务进程数可以开多一些,例如cpu的10倍,然后调用方利用AsyncTcpConnection将数据异步发送给这些任务进程异步处理,异步得到处理结果

任务进程服务端

use WorkermanWorker;
require_once __DIR__ . '/Workerman/Autoloader.php';
// task worker,使用Text协议
$task_worker = new Worker('Text://0.0.0.0:12345');
// task进程数可以根据需要多开一些
$task_worker->count = 100;
$task_worker->name = 'TaskWorker';
//只有php7才支持task->reusePort,可以让每个task进程均衡的接收任务
//$task->reusePort = true;
$task_worker->onMessage = function($connection, $task_data)
{
 // 假设发来的是json数据
 $task_data = json_decode($task_data, true);
 // 根据task_data处理相应的任务逻辑.... 得到结果,这里省略....
 $task_result = ......
 // 发送结果
 $connection->send(json_encode($task_result));
};
Worker::runAll();

在workerman中调用

use WorkermanWorker;
use WorkermanConnectionAsyncTcpConnection;
require_once __DIR__ . '/Workerman/Autoloader.php';
// websocket服务
$worker = new Worker('websocket://0.0.0.0:8080');
$worker->onMessage = function($ws_connection, $message)
{
 // 与远程task服务建立异步连接,ip为远程task服务的ip,如果是本机就是127.0.0.1,如果是集群就是lvs的ip
 $task_connection = new AsyncTcpConnection('Text://127.0.0.1:12345');
 // 任务及参数数据
 $task_data = array(
 'function' => 'send_mail',
 'args' => array('from'=>'xxx', 'to'=>'xxx', 'contents'=>'xxx'),
 );
 // 发送数据
 $task_connection->send(json_encode($task_data));
 // 异步获得结果
 $task_connection->onMessage = function($task_connection, $task_result)use($ws_connection)
 {
 // 结果
 var_dump($task_result);
 // 获得结果后记得关闭异步连接
 $task_connection->close();
 // 通知对应的websocket客户端任务完成
 $ws_connection->send('task complete');
 };
 // 执行异步连接
 $task_connection->connect();
}
Worker::runAll();

这样,繁重的任务交给本机或者其它服务器的进程去做,任务完成后会异步收到结果,业务进程就不会阻塞了。

更多Workerman相关技术文章,请访问Workerman教程栏目进行学习!

下载本文
显示全文
专题