swoole_server->task
投递一个异步任务到task_worker池中。此函数会立即返回。worker进程可以继续处理新的请求。
bool swoole_server::task(mixed $data, int $dst_worker_id = -1) $task_id = $serv->task("some data");
- $task_id在全局不唯一,在调用task的event进程中唯一,task id范围 0 - 42亿
- $data要投递的任务数据,可以为除资源类型之外的任意PHP变量
- $dst_worker_id可以制定要给投递给哪个task进程,传入ID即可,范围是0 - serv->task_worker_num
- 返回值为整数($task_id),表示此任务的ID。如果有finish回应,onFinish回调中会携带$task_id参数
例子:task实现db pool
<?php $serv = new swoole_server("127.0.0.1", 9500); $serv->set(array( 'worker_num' => 1, 'task_worker_num' => 8, //database connection pool 'db_uri' => 'mysql:host=127.0.0.1;dbname=test', 'db_user' => 'root', 'db_passwd' => 'root', // 'task_worker_max'=>100 )); function my_onReceive($serv, $fd, $from_id, $data) { $result = $serv->taskwait($data); if ($result !== false) { list($status, $db_res) = explode(':', $result, 2); if ($status == 'OK') { $serv->send($fd, var_export(unserialize($db_res), true) . "\n"); } else { $serv->send($fd, $db_res); } return; } else { $serv->send($fd, "Error. Task timeout\n"); } } function my_onTask($serv, $task_id, $from_id, $sql) { static $link = null; if ($link == null) { $link = new PDO($serv->setting['db_uri'], $serv->setting['db_user'], $serv->setting['db_passwd']); if (!$link) { $link = null; $serv->finish("ER: connect database failed."); return; } } $result = $link->query($sql); if (!$result) { $serv->finish("ER: query error"); return; } $data = $result->fetchAll(); $serv->finish("OK:" . serialize($data)); } function my_onFinish($serv, $data) { echo "AsyncTask Finish:Connect.PID=" . posix_getpid() . PHP_EOL; } $serv->on('Receive', 'my_onReceive'); $serv->on('Task', 'my_onTask'); $serv->on('Finish', 'my_onFinish'); $serv->start();
$dst_worker_id在1.6.11+后可用,默认为随机投递
$task_id是从0-42亿的整数,在当前进程内是唯一的
task方法不能在task进程中调用
此功能用于将慢速的任务异步地去执行,比如一个聊天室服务器,可以用它来进行发送广播。
当任务完成时,在task进程中调用$serv->finish("finish")
告诉worker进程此任务已完成。当然swoole_server->finish
是可选的。
task底层使用Unix Socket管道通信,是全内存的,没有IO消耗。单进程读写性能可达100万/s,不同的进程使用不同的管道通信,可以最大化利用多核。
AsyncTask功能在1.6.4版本增加,默认不启动task功能,需要在手工设置task_worker_num来启动此功能
task_worker的数量在swoole_server::set参数中调整,如task_worker_num => 64,表示启动64个进程来接收异步任务
swoole_server_task和swoole_server_finish在版本swoole-1.7.16-stable发送$data的长度可以超过8K, 此参数受SW_BUFFER_SIZE宏控制 。超过8k的数据默认是用/tmp作为临时存储
配置参数
swoole_server->task/taskwait/finish 3个方法当传入的$data
数据超过8K时会启用临时文件来保存。当临时文件内容超过 server->package_max_length
时底层会抛出一个警告。
WARN: task package is too big.
server->package_max_length 默认为2M
注意事项
- 使用swoole_server_task必须为Server设置onTask回调,否则
swoole_server->start
会失败,onFinish回调可选,task任务完成后调用onFinish回调 - task操作的次数必须小于onTask处理速度,如果投递容量超过处理能力,task会塞满缓存区,导致worker进程发生阻塞。worker进程将无法接收新的请求