2

私はこの質問から始めました: ギアマン: クライアントのリクエストとワーカーの受信の間に 3 秒。これは正常ですか?

環境:

  • Ubuntu 12.04 デスクトップ
  • PHP 5.3.10
  • Gearman (libgearman 1.1.5 と PHP 拡張機能 1.1.1)
  • LAN上の複数のサーバー

ワーカーの応答時間を 3 秒未満にすることができず、その理由がわかりませんでした。私が構築したラッパークラスに絞り込みました。次に、クラス内の特定のメソッドにさらに絞り込みました。簡単に言えば、実際の問題は、PHP 拡張機能の GearmanWorker の addServer メソッドにあるようです。

ラッパー クラスが 3 つの Gearman Job Server に接続しようとしていました。実際に稼働しているのは2つだけです。3つすべてに接続しようとすると、3番目が接続できないという警告が表示されます。また、ワーカーの応答時間は 3 秒です。現在ダウンしているジョブ サーバーに addServer の試行を削除すると、ワーカーの応答時間は約 0.003 秒になります。

ここで、接続先のサーバーのリストから停止中のサーバーを削除してみませんか?と尋ねるかもしれません。まず、常にダウンしているわけではありません。第 2 に、現在稼働中または 5 分前に稼働していたサーバーの 1 つがもはや稼働していない場合はどうなるでしょうか? すべてのジョブが最低 3 秒かかるようになりました。おそらく、そのタイムアウトを 1 秒に設定する方法があると思いますが、IMO のより良い解決策は、ワーカーがジョブを取得しようとしているサーバーのリストからデッド サーバーを削除する方法があることです。

私の研究では addServer メソッドがあります。そして addFunction メソッドがあります。次に、特定のワーカーのリストからワーカー機能を削除する unregister メソッドがあります。ただし、removeServer メソッドは表示されません。

では、GearmanWorker でジョブ サーバーのリストを選別する方法はありますか?それとも、オブジェクトを強制終了して再インスタンス化し、選別された新しい使用可能なジョブ サーバーのリストに再接続する必要がありますか? GearmanWorker を強制終了して再起動することは、理想とはほど遠いようです。

停止したジョブ サーバーに固有のタイムアウトを回避しながら、すべてのアクティブなジョブ サーバーをスキャン (および接続) する最良の方法は何ですか?

ありがとう

4

1 に答える 1

1

したがって、最終的に、この問題を抱えているのは私だけではないようです。Gearman の Google グループの誰も解決策を指摘できませんでした。そのため、最終的には独自のコードを作成し (Gearman Monitor から一部を抜粋して)、稼働しているジョブ サーバーと稼働していないジョブ サーバーを特定しました。

try {
            $cxn = @fsockopen($ip, $gHosts->ports[$host], $errCode, $errMsg, $timeout);

            /* Using the new \Net_Gearman_Manager on a dead job server kept leading to
             *  fatal error which was uncaught. Thus crashing the script and leading
             *  no update of the server status
            */
            //$gearmanManager = new \Net_Gearman_Manager($ip . ':' . $gHosts->ports[$host], 1);

            if ($cxn === FALSE) {
                write_log($fLog, 'Connection FAILED');
                $output[$host] = FAILURE;
            } else {
                write_log($fLog, 'Connection Succeeded');
                $output[$host] = SUCCESS;
            }
        } catch (Net_Gearman_Exception $e) {
            write_log($fLog, $e->getMessage());
            $output[$host] = FAILURE;
        } catch (Exception $e) {
            write_log($fLog, $e->getMessage());
            $output[$host] = FAILURE;
        } // if (@$wrkr->addServer($ip, $gHosts->ports[$host]))

$gHosts クラスは、潜在的な Gearman ジョブ サーバーのそれぞれの IP とポートを保持する構成クラスです。$gHosts 内の潜在的な各ジョブ サーバーをスピンしてテストします。

次に、この出力を memcache とテキスト ファイルに書き込みます。実際にマシンをロードしようとするまでは、memcache だけでも問題なく動作していました。その後、memcache 接続が繰り返し失敗します。テキストファイルをバックアップとして使用すると、問題はなくなりました。

各 Gearman Job Server への最後の接続試行を配列に格納します。キーはサーバーの名前で、値は最後の試行のタイム スタンプです。試行が成功した場合、タイムスタンプは正です。試行が失敗した場合、タイム スタンプは負になります。タイムスタンプにより、データが古いか新しいかを判断できます。

次に、Gearman を使用するスクリプトには、PHP 拡張クラスの周りに Client および Worker ラッパー クラスがあります。彼らは、私が望む時間枠で自動的に接続を更新します。そうすれば、応答を停止した Gearman Job Server は使用されなくなり、スクリプトは、短時間は遅くなる可能性がありますが、通常は非常に高速に実行されます。

これが誰かを助けることを願っています。

于 2013-10-31T23:28:20.770 に答える