× 警告!旧版文档已经暂停维护,请查看新版文档。点击前往新版文档

在php-fpm/apache中使用task功能

AsyncTask是swoole提供一套生产者消费者模型,可以方便地将一个慢速任务投递到队列,由进程池异步地执行。task功能目前只能在swoole_server中使用。1.9.0版本提供了RedisServer框架,可以基于RedisServer和Task实现一个Server程序,在php-fpm或apache中直接调用Redis扩展就可以使用swoole的task功能了。

创建RedisServer

use Swoole\Redis\Server;

$server = new Server("127.0.0.1", 9501, SWOOLE_BASE);

$server->set(array(
    'task_worker_num' => 32,
    'worker_num' => 1,
));

$server->setHandler('LPUSH', function ($fd, $data) use ($server) {
    $taskId = $server->task($data);
    if ($taskId === false)
    {
        return Server::format(Server::ERROR);
    }
    else
    {
        return Server::format(Server::INT, $taskId);
    }
});

$server->on('Finish', function() {

});

$server->on('Task', function ($serv, $taskId, $workerId, $data) {
    //处理任务
});

$server->start();
  • 如果是本机调用可以监听UnixSocket,局域网内调用需要使用IP:PORT
  • Task中$data就是客户端投递的数据
  • 其他语言也可以使用Redis客户端投递任务
  • 可以根据Task任务执行的速度调节task_worker_num控制启动的进程数量,这些进程是由swoole底层负责管理的,在发生致命错误或进程退出后底层会重新创建新的任务进程

投递任务

$redis = new Redis;
$redis->connect('127.0.0.1', 9501);
$taskId = $redis->lpush("myqueue", json_encode(array("hello", "swoole")));

注意这个RedisServer并不是一台真正的Redis服务器,它只支持LPUSH一个指令。


  • fifsky

  • copperfield

  • 坐忘丿夏虫语冰

    不能多次投递啊 一次只能执行一次$taskId = $redis->lpush("myqueue", json_encode(array("hello", "swoole")));

  • 大佬黄

    这个on('Task')里面该怎么写啊,怎么我client能接收到taskid,但是onTask里面的方法感觉一直没运行啊

  • pj

    onFinish(swoole_server $serv, int $task_id, string $data); 如果要在onFinish中发送消息给客户端,怎么获得连接的描述符呢?

  • 换个昵称喽

    怎么查看队列里边的数量呢?

  • yiuked

    客户端为什么会阻塞呢?

  • 吴道林

    试了下

    1. SWOOLE_BASE 没有manager进程
    2. kill -USR2/1 master_pid 只会重启worker进程,task进程不会重启
    3. 使用systemd管理swoole服务, 按这个来,使用systemctl reload swoole_task.service 命令效果跟上面一样,task进程也不会重启

  • 吴道林

    SWOOLE_BASE 应该就是不行,换成 SWOOLE_PROCESS 就好了

  • 我兜里有糖

    难道就我一个人遇到客户端投递任务阻塞这个问题么

  • 我兜里有糖

    难道就我一个人遇到客户端lpush阻塞这个问题么