Механизм, работающий в CLI, но не в браузере - GEARMAN_COULD_NOT_CONNECT (485)

1

У меня есть два сценария PHP (рабочий и клиент) для выполнения задач в paralell с использованием Gearman.

Сервер работает правильно, а скрипты также, если вызывается из командной строки моего CentOS 6. Проблема возникает, когда я запускаю эти сценарии из браузера, этот ответ не возвращался.

Когда я запускаю свой клиентский скрипт, который, в свою очередь, нужен экземпляр работников, по командной строке, я получаю этот результат:

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();

Client.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);
  • 1
    При вызове через браузер скрипт выполняется намного быстрее, поэтому, вероятно, не каждый код был запущен. Вероятно, у вас будет пользователь с доступом к оболочке. У этого пользователя могут быть разрешения (например, proc_open() ), которых нет у пользователя apache. Так что проверьте различные разрешения с подробным сообщением об ошибках ( error_reporting(E_ALL); и ini_set('display_errors', 1); ) и посмотрите, error_reporting(E_ALL); ли оно какие-либо ошибки.
  • 0
    Спасибо @Jan, я понимаю. Как только я показываю ошибки, которые произошли, я возвратил следующую ошибку : Предупреждение: GearmanClient :: runTasks (): send_packet (GEARMAN_COULD_NOT_CONNECT) Не удалось отправить пакет опций сервера -> libgearman / connection.cc: 485 в / var / www / html / web / Client.php в строке 157 ¿Знаете ли вы, о чем это?
Показать ещё 4 комментария
Теги:
gearman

1 ответ

0
Лучший ответ

Я нашел решение, поскольку, как я думал, он не был связан с кодом или механизмом, который должен был быть частью конфигурации обслуживания. Дело в том, что я нашел эту дискуссию 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

Надеюсь, что кто-то поможет.

  • 1
    Измените вопрос также для будущих посетителей на что-то более актуальное. Я бы сделал это сам, но понятия не имею, как это назвать.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню