4

Gearman デーモンが実行されているかどうかを確認したい。そして、タスクを実行して、アプリケーションがクラッシュしないようにします。

これが私のコードです:

$daemonRunning = true;

while( true )
{
    try
    {
        Yii::app()->gearman->client->ping( true );

        if ( $daemonRunning === false )
        {
            echo "Daemon back online. Starting signature process...\n";
        }

        Yii::app()->gearman->client->runTasks();
    }
    catch( GearmanException $e )
    {
        echo "Daemon appears to be down. Waiting for it to come back up...\n";
        $daemonRunning = false;
    }
    sleep(1);
}

しかし、問題はping例外をスローせず、致命的なエラーをスローすることです:

PHP Error[2]: GearmanClient::ping(): flush(GEARMAN_COULD_NOT_CONNECT) 127.0.0.1:4730 -> libgearman/connection.cc:673

奇妙なことに、 を削除pingして のみを使用するとrunTasks、例外がスローされます。

関連している:

プロセスの実行中に Gearman デーモンがダウンした場合のエラーを処理するにはどうすればよいですか? Gearman デーモンを停止すると、PHP から次のエラーが表示されます。

php: libgearman/universal.cc:481: gearman_return_t connection_loop(gearman_universal_st&, const gearman_packet_st&, Check&): Assertion `&con->_packet == universal.packet_list' failed.
Aborted (core dumped)
4

1 に答える 1

14

最も基本的なこととして、Gearman サーバーのステータスを確認するには、次のコマンド ラインを使用します。

(echo status ; sleep 0.1) | nc 127.0.0.1 4730 -w 1

ただし、この質問に記載されているようfsocketopenに、ギアマン サーバーのステータスを取得するために使用できます。

 // Taken from https://stackoverflow.com/questions/2752431/any-way-to-access-gearman-administration
class Waps_Gearman_Server {

    /**
     * @var string
     */
    protected $host = "127.0.0.1";
    /**
     * @var int
     */
    protected $port = 4730;

    /**
     * @param string $host
     * @param int $port
     */
    public function __construct($host=null,$port=null){
        if( !is_null($host) ){
            $this->host = $host;
        }
        if( !is_null($port) ){
            $this->port = $port;
        }
    }

    /**
     * @return array | null
     */
    public function getStatus(){
        $status = null;
        $handle = fsockopen($this->host,$this->port,$errorNumber,$errorString,30);
        if($handle!=null){
            fwrite($handle,"status\n");
            while (!feof($handle)) {
                $line = fgets($handle, 4096);
                if( $line==".\n"){
                    break;
                }
                if( preg_match("~^(.*)[ \t](\d+)[ \t](\d+)[ \t](\d+)~",$line,$matches) ){
                    $function = $matches[1];
                    $status['operations'][$function] = array(
                        'function' => $function,
                        'total' => $matches[2],
                        'running' => $matches[3],
                        'connectedWorkers' => $matches[4],
                    );
                }
            }
            fwrite($handle,"workers\n");
            while (!feof($handle)) {
                $line = fgets($handle, 4096);
                if( $line==".\n"){
                    break;
                }
                // FD IP-ADDRESS CLIENT-ID : FUNCTION
                if( preg_match("~^(\d+)[ \t](.*?)[ \t](.*?) : ?(.*)~",$line,$matches) ){
                    $fd = $matches[1];
                    $status['connections'][$fd] = array(
                        'fd' => $fd,
                        'ip' => $matches[2],
                        'id' => $matches[3],
                        'function' => $matches[4],
                    );
                }
            }
            fclose($handle);
        }

        return $status;
    }

}

2 番目の質問に関しては、作業中に接続が失われたときにギアマン ワーカーを回復できたことは一度もありません。基本的に、クライアントワーカーを実行しているプロセス全体を強制終了し、スーパーバイザーに引き継いで別のワーカープロセスを再起動させる必要があります。Gearman のクライアント ワーカーは、非常に一時的なものにする必要があります。それらのメモリ使用量を定期的に監視し、自動で強制終了する必要があります。そのため、segfault/コアダンプに遭遇した場合、ワーカーを強制終了するのはまったく正常です。

前述のように、Supervisor を使用してワーカーのバックアップを自動で開始できます。これもチェックしてください。Gearman Client を Supervisor と連携させる方法について説明しています。

于 2012-11-05T10:37:59.880 に答える