【问题标题】:Gearman working in CLI but not in browser - GEARMAN_COULD_NOT_CONNECT (485)Gearman 在 CLI 中工作但不在浏览器中 - GEARMAN_COULD_NOT_CONNECT (485)
【发布时间】:2015-11-23 12:49:00
【问题描述】:

我有两个 PHP 脚本(worker 和 client)使用 Gearman 并行执行任务。

服务器运行正常,如果从我的 CentOS 6 的命令行执行,脚本也运行正常。当我从 浏览器 运行这些脚本时,问题就出现了,则未返回此响应。

当我通过命令行运行我的客户端脚本时,它又需要worker实例,我得到这个结果:

Got in: 2.04 seconds
string (20) "soidA321esa q alO321"

但如果我从您的网络浏览器运行它,我会得到这个:

Got in: 0.02 seconds
NULL

我不知道为什么它以一种方式正常工作而不是另一种方式。 有人发生过或知道可能会发生类似的事情吗?

您好,谢谢。

PS:所涉及的附加代码:

Worker.php

<?php

class GrmWorker
{

    /**
     * Declaración de atributos.
     */
    private $worker;

    /**
     * Constructor de la clase.
     */ 
    public function __construct()
    {
        // Instancia un nuevo Worker.
        $this->worker = new \GearmanWorker();
    }

    /**
     * Añade un servidor de trabajo a una lista de servidores que pueden ser usados para ejecutar trabajos. 
     */
    public function addServer(array $servers = array())
    {
        // Comprueba si se envían los parámetros de servidor o se establecen los predeterminados.
        if (sizeof($servers) == 0)
        {
            $this->worker->addServer('127.0.0.1', '4730');
        }
        else
        {
            // Recorre el array de servidores.
            foreach ($servers as $server)
            {
                // Comprueba que los índices de los parámetros sean correctos.
                if (null !== $server['host'] && null !==$server['port']) 
                {
                    $this->worker->addServer($server['host'], $server['port']);
                }
                else
                {
                    throw new Exception('El array de servidores solo puede contener los índices "host" y "port".');
                }
            }
        }
    }

    /**
     * Registra el nombre de una función en el servidor de trabajos y especifica la llamada de retorno quer corresponde a esa función.
     */
    public function addFunction($functionName, callable $function)
    {
        $this->worker->addFunction($functionName, $function);
    }

    /**
     * Establece el intervalo de tiempo, en milisegundos, en el cual estará disponible el Worker.
     */
    public function setTimeout($miliseconds)
    {
        $this->worker->setTimeout($miliseconds);
    }

    /**
     * Retorna el tiempo actual a esperar, en milisegundos.
     */
    public function timeout()
    {
        $this->worker->timeout();
    }

    /**
     * Pone a funcionar el trabajador.
     */
    public function work()
    {
        while ($this->worker->work());
    }
}

/**
 * Clase que contiene as funciones a declarar para el trabajador.
 */
class Functions
{
    public static function reverse_cb($job)
    {
        sleep(2);

        return strrev('123' . $job->workload());
    }
}

// Instancia un nuevo trabajador.
$worker = new GrmWorker();
$worker->addServer();
$worker->setTimeout(60000);

// Declara las funciones que puede ejecutar el trabajador.
$worker->addFunction("reverse", "Functions::reverse_cb");

// Comienza a trabajar.
$worker->work();

客户端.php

<?php

class GrmClient
{
    // Declaración de atributos.
    private $client;
    private $tasks;

    /**
     * Constructor de la clase.
     */
    public function __construct()
    {
        $this->client = new GearmanClient();
        $this->tasks = 0;
    }

    /**
     * Añade un servidor de trabajo a una lista de servidores que pueden ser usados para ejecutar trabajos.
     */
    public function addServer(array $servers = array())
    {
        // Comprueba si se envían los parámetros de servidor o se establecen los predeterminados.
        if (sizeof($servers) == 0)
        {
            $this->client->addServer('127.0.0.1', '4730');
        }
        else
        {
            // Recorre el array de servidores.
            foreach ($servers as $server)
            {
                // Comprueba que los índices de los parámetros sean correctos.
                if (null !== $server['host'] && null !== $server['port']) 
                {
                    $this->client->addServer($server['host'], $server['port']);
                }
                else
                {
                    throw new Exception('El array de servidores solo puede contener los índices "host" y "port".');
                }
            }
        }
    }

    /**
     *  Añade una tarea para ser ejecutada en paralelo.
     */
    public function addTask($function_name, $workload, mixed $context = null)
    {
        $this->client->addTask($function_name, $workload, $context);

        // Aumenta el contador de tareas a ejecutar.
        $this->tasks++;
    }

    /**
     *  Ejecuta una tarea en segundo plano para ser ejecutada en paralelo.
     */
    public function addTaskBackground($function_name, $workload, mixed $context = null)
    {
        $this->client->addTaskBackground($function_name, $workload, $context);

        // Aumenta el contador de tareas a ejecutar.
        $this->tasks++;
    }

    /**
     *  Añade una tarea de alta prioridad para ser ejecutada en paralelo.
     */
    public function addTaskHigh($function_name, $workload, mixed $context = null)
    {
        $this->client->addTaskHigh($function_name, $workload, $context);

        // Aumenta el contador de tareas a ejecutar.
        $this->tasks++;
    }

    /**
     *   Añade una tarea de alta prioridad para ser ejecutada en segundo plano y en paralelo.
     */
    public function addTaskHighBackground($function_name, $workload, mixed $context = null)
    {
        $this->client->addTaskHighBackground($function_name, $workload, $context);

        // Aumenta el contador de tareas a ejecutar.
        $this->tasks++;
    }

    /**
     *  Añade una tarea de baja prioridad para ejecutar en paralelo.
     */
    public function addTaskLow($function_name, $workload, mixed $context = null)
    {
        $this->client->addTaskHigh($function_name, $workload, $context);

        // Aumenta el contador de tareas a ejecutar.
        $this->tasks++;
    }

    /**
     *  Añade una tarea de baja prioridad para ser ejecutada en segundo plano y en paralelo.
     */
    public function addTaskLowBackground($function_name, $workload, mixed $context = null)
    {
        $this->client->addTaskHighBackground($function_name, $workload, $context);

        // Aumenta el contador de tareas a ejecutar.
        $this->tasks++;
    }

    /**
     * Especifica una función a ser llamada cuando se complete una tarea. La función de llamada de retorno acepta un único argumento, un objeto GearmanTask.
     */
    public function setCompleteCallback(callable $function)
    {
        $this->client->setCompleteCallback($function);
    } 

    /**
     * Elimina todas las funciones de retorno de llamada establecidas.
     */
    public function clearCallbacks()
    {
        $this->client->clearCallbacks();
    }

    /**
     * Ejecuta una lista de tareas, previamente establecidas, en paralelo.
     */
    public function runTasks()
    {   
        // Declara el array que contendrá los recursos que manejan los procesos de los workers.
        $process = array();

        // Comprueba si existen suficientes Workers para las tareas solicitadas.
        if ($this->getNumWorkers() < $this->getNumTasks())
        {
            for ($i = 0; $i < $this->getNumTasks() - $this->getNumWorkers(); $i++)
            {
                // Pone en marcha un worker en segundo plano.
                $proce = proc_open("php /var/www/html/web/Worker.php > /dev/null &",
                        array(
                                array("pipe","r"),
                                array("pipe","w"),
                                array("pipe","w")
                        ),
                        $pipes);
                $process[] = $proce;
            }
        }

        // Ejecuta las tareas puestas en cola.
        $this->client->runTasks();

    }

    /**
     * Devuelve el número de tareas definidas.
     */
    public function getNumTasks()
    {
        return $this->tasks;
    }

    /**
     * Devuelve el número de trabajadores activos.
     */
    private function getNumWorkers()
    {
        $workers = shell_exec ("gearadmin --workers");
        $workers = explode(PHP_EOL, $workers);
        return sizeof($workers) - 3;
    }
}

$client = new GrmClient();
$client->addServer();

$result = null;

$client->setCompleteCallback(function(GearmanTask $task) use (&$result)
{
    $result .= $task->data();
});

$client->addTask('reverse', 'Ola q ase');
$client->addTask('reverse', 'Adios');

$start = microtime(true);
$client->runTasks();
$totaltime = number_format(microtime(true) - $start, 2);

echo "Got in: " . $totaltime . " seconds \n";
var_dump($result);

【问题讨论】:

  • 当通过浏览器调用时,脚本要快得多,因此可能不是每个代码都已运行。可能您将拥有一个具有 shell 访问权限的用户。该用户可能拥有 apache 用户没有的权限(如 proc_open())。因此,请使用详细的错误消息(error_reporting(E_ALL);ini_set('display_errors', 1);)检查不同的权限,看看它是否会引发任何错误。
  • 谢谢 @Jan 我明白了。一旦我显示发生的错误,我返回以下 errorWarning: GearmanClient::runTasks(): send_packet(GEARMAN_COULD_NOT_CONNECT) Failed to send server-options packet -> libgearman/connection.cc :485 在 /var/www/html/web/Client.php 第 157 行 ¿你知道它是关于什么的吗?
  • 未设置端口 (4730) 时会出现这种情况,请参阅here on SO for more information
  • 嗨@Jan 在代码中,添加服务器时明确声明连接端口。 addServer('127.0.0.1', '4730') THX
  • 请接受您自己的答案并删除“已解决...”

标签: php apache gearman


【解决方案1】:

我发现解决方案,我认为与代码或齿轮人无关,应该是某种服务配置。关键是我发现了这场辩论 https://groups.google.com/forum/#!topic/gearman/_dW8SRWAonw 并通过 SHH 执行以下 命令

进入MAC控制强制执行许可模式。

[root @ localhost share] # getenforce
enforcing
[root @ localhost share] # setenforce 0
[root @ localhost share] # getenforce
permissive

希望有人帮忙。

【讨论】:

  • 也为未来的访问者将问题更改为更相关的问题。我会自己做,但我不知道该怎么称呼它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-14
  • 1970-01-01
  • 1970-01-01
  • 2021-09-18
  • 1970-01-01
  • 2014-03-27
  • 2021-05-10
相关资源
最近更新 更多