español - gearman php
Gearman lento cuando el cliente envía gran carga útil (1)
Tengo un problema al utilizar Gearman que demora en transferir las tareas a los trabajadores cuando le envío grandes cargas útiles a través de la extensión PHP de Gearman. De hecho, no encontramos que la carga útil sea tan grande (es de 30 MB). Todo (PHP, Gearman, nodo) se ejecuta localmente por ahora, por lo que el acceso a la red no es el cuello de botella.
El script PHP
Aquí está el cliente 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);
Este es mi trabajador de nodejs que eventualmente hará algo, pero está vacío para demostrar que el código de trabajador no es un problema:
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!'');
});
Empiezo a mi trabajador en segundo plano y luego ejecuto mi cliente, y se congela mientras $client->doNormal
30 segundos mientras se $client->doNormal
(justo después de enviar el trabajo de envío a Gearman ), y finaliza emitiendo la string(7) "Toasty!"
a través de var_dump de PHP. Así que funciona, pero su proceso es largo.
Además, si reduzco el tamaño de la carga útil (data.json), lleva menos tiempo, por lo que el tamaño de la carga útil parece ser importante.
Intenté codificar el mismo trabajador en PHP, con el mismo resultado:
$worker= new GearmanWorker();
$worker->addServer(''127.0.0.1'', ''4730'');
$worker->addFunction("validateJsonSchema", "validateJsonSchema");
while ($worker->work());
function validateJsonSchema($job)
{
return ''ToastyPHP!'';
}
ACTUALIZAR
Usando el cliente node.js, haciendo casi lo mismo que en PHP, se ejecuta mucho más rápido (~ 3.5 segundos). ¿Estoy haciendo algo mal con la versión de PHP, o me estoy perdiendo alguna configuración para hacerlo más rápido?
Mi cliente 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
});
¿Alguna pista de por qué está sucediendo esto? ¿Está Gearman hecho para manejar este tamaño de carga útil? 30MB no es tan grande en mi libro.
Compruebe si este código funciona para usted, tomó muy poco tiempo para completar el trabajo.
worker.php :
echo "Starting/n";
$gmworker = new GearmanWorker();
# Add default server (localhost).
$gmworker->addServer(''127.0.0.1'', ''4730'');
$gmworker->addFunction("jsonValid", "jsonValid");
print "Waiting for job.../n";
while ($gmworker->work()) {
if ($gmworker->returnCode() != GEARMAN_SUCCESS) {
echo "return_code: " . $gmworker->returnCode() . "/n";
break;
}
}
function jsonValid($job)
{
return ''ToastyPHP!'';
}
Client.php
ini_set(''memory_limit'', ''1G'');
$client = new GearmanClient();
$client->addServer(''127.0.0.1'', ''4730'');
$client->setCompleteCallback("complete");
$time = time();
echo "<pre>Sending job..." . "/n";
$schema = file_get_contents(''AllSets.json'');
$data = file_get_contents(''AllSets.json'');
$gearmanData = Array(
''schema'' => $schema,
''data'' => $data
);
$gearmanDataString = json_encode($gearmanData, JSON_FORCE_OBJECT);
$client->addTask("jsonValid", $gearmanDataString, null, ''Json'');
$client->runTasks();
echo "Job finished/n";
$endtime = time();
print "Completed in " . ($endtime - $time) . '' seconds'' . "/n";
function complete($task)
{
print "Unique : " . $task->unique() . "/n";
print "Data : " . $task->data() . "/n";
}
He utilizado los métodos addTask y runTasks en lugar de doNormal.Para enviar los datos json, utilicé el archivo AllSets.json de http://mtgjson.com/ en un tamaño de aproximadamente 30Mb (carga total), el trabajo finalizado en 1 segundo, y después de probar un archivo de alrededor de 200 Mb tomó 4 segundos.