我在使用Gearman时遇到了问题,当我通过Gearman PHP扩展发送大型负载时,向工作进程传输任务速度非常慢。实际上,我们认为负载并不是很大(只有30MB)。目前所有内容(PHP、Gearman、node)都在本地运行,所以网络访问不是瓶颈。
这是PHP客户端的代码:
ini_set('memory_limit', '1G');
$client= new GearmanClient();
$client->addServer('127.0.0.1', '4730');
$schema = file_get_contents('schema.json');
$data = file_get_contents('data.json');
$gearmanData = [
'schema' => $schema,
'data' => $data
];
echo "Encoding in JSON the payload\n";
$gearmanDataString = json_encode($gearmanData, JSON_FORCE_OBJECT);
echo "Sending job to Gearman\n";
// This line takes long to execute...
$result = $client->doNormal("validateJsonSchema", $gearmanDataString);
echo "Job finished\n";
var_dump($result);
这是我的Node.js worker,最终将要做一些事情,但现在为空,以证明worker代码不是问题:
var gearmanode = require('gearmanode');
var worker = gearmanode.worker({host: '127.0.0.1' port: 4730});
worker.addFunction('validateJsonSchema', function (job) {
console.log('I will do something');
job.workComplete('Toasty!');
});
我在后台启动了我的工作进程,然后运行客户端,在执行$client->doNormal
时(刚刚输出发送工作到Gearman),它会冻结30秒左右,最后通过PHP的var_dump输出string(7) "Toasty!"
。所以它可以工作,但是处理时间太长。
此外,如果我减少负载的大小(data.json),那么处理时间就会更短,因此负载大小似乎很重要。
我尝试用相同的PHP代码编写了同样的工人程序,并得到了相同的结果:
$worker= new GearmanWorker();
$worker->addServer('127.0.0.1', '4730');
$worker->addFunction("validateJsonSchema", "validateJsonSchema");
while ($worker->work());
function validateJsonSchema($job)
{
return 'ToastyPHP!';
}
更新
使用node.js客户端,与PHP实现几乎相同的功能,执行速度更快(约3.5秒)。我在PHP版本中做错了什么,或者我缺少一些配置使其更快?
我的node.js客户端:
var gearmanode = require('gearmanode');
var fs = require('fs');
var start = Date.now();
var client = gearmanode.client();
schema = fs.readFileSync('schema.json', 'utf8');
data = fs.readFileSync('data.json', 'utf8');
var submitData = JSON.stringify({ "data": data, "schema": schema });
// Runs much faster than PHP
var job = client.submitJob('validateJsonSchema', submitData, {background: false});
job.on('complete', function() {
console.log('RESULT >>> ' + job.response);
client.close();
var end = Date.now();
console.log(end-start + ' milliseconds'); // Always shows around 3500 milliseconds
});
你知道这是为什么吗?Gearman 能处理这种大小的有效载荷吗?在我看来,30MB 并不算太大。