2017-02-23 1 views
0

私は3つのbeanstalkdキュープロセスを同じipでも異なるポートで実行しています。キューを処理するためにスーパーバイザがPHPワーカーを並列に起動する別のサーバー(Beanstalkdポートあたり20個)を持っています。私の問題は、2つのプロセスが同じ時間に同じサーバー上で同じジョブIDを予約できるように思われることです。同じbeanstalkdジョブを2回以上予約しているPheanstalk

2017-02-23 09:59:56 --> START JOB (port: 11301 | u: 0.45138600 1487861996 | jid:1695074 | pid:30019 | j:leads_to_tags_add | tr:1) 
2017-02-23 09:59:57 --> START JOB (port: 11301 | u: 0.55024800 1487861997 | jid:1695074 | pid:30157 | j:leads_to_tags_add | tr:2) 
2017-02-23 09:59:58 --> DEL JOB (port: 11301 | u: 0.54731000 1487861998 | jid:1695074 | pid:30019 | j:leads_to_tags_add) 
2017-02-23 09:59:58 --> DEL JOB (port: 11301 | u: 0.58927900 1487861998 | jid:1695074 | pid:30157 | j:leads_to_tags_add) 

2つの埋蔵が右互いの後に起こるようで、第二の予備が最初のプロセスが終了する前に発生し、ジョブを削除します。ここでは

は私のログからいくつかのサンプル出力です。

私はジョブIDごとに赤字でカウンタを追加しました.2回目の予約時には、カウンタは1回上がりました(tr)。 TTRRは3600に設定されているため、最初のプロセスが完了する前に期限切れになることはありません。

これは、ジョブの状態は、第二の処理準備金の後に右のようになります。

Pheanstalk\Response\ArrayResponse::__set_state(array(
    'id' => '1695074', 
    'tube' => 'action-medium', 
    'state' => 'reserved', 
    'pri' => '0', 
    'age' => '1', 
    'delay' => '0', 
    'ttr' => '3600', 
    'time-left' => '3599', 
    'file' => '385', 
    'reserves' => '2', 
    'timeouts' => '0', 
    'releases' => '0', 
    'buries' => '0', 
    'kicks' => '0', 
)) 

この動作は、時には、非常にランダムであり、時には唯一のプロセスがジョブがロックするまでに予約することができます、時には2 4つ以上(まれに)。もちろん、これにより、実行される重複ジョブの数が不一致になります。コードの

ショートバージョン:

$this->job = $this->pheanstalk->watch($tube)->reserve($timeout); 


set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) { 
    // error was suppressed with the @-operator 
    if (0 === error_reporting()) { 
     return false; 
    } 

    throw new ErrorException($errstr, 0, $errno, $errfile, $errline); 
}); 

$this->log_message('info', __METHOD__ . ": START JOB (" . $this->_logDetails() . " | tr:{$tries})"); 


if ($this->_process_job()) { 
    $this->log_message('info', __METHOD__ . ": FINISHED JOB (" . $this->_logDetails() . ")"); 
    $this->_delete_job(); 
} else { 
    $this->log_message('error', __METHOD__ . ": FAILED JOB (" . $this->_logDetails() . ")"); 
} 

restore_error_handler(); 

protected function _delete_job() 
{ 
    $this->pheanstalk->delete($this->job); 
    $this->log_message('info', __METHOD__ . ": DELETED JOB (" . $this->_logDetails() . ")"); 
} 
+0

ジョブを予約し、作業するために送信し、完了したらコードを '削除 'してください。 –

+0

@AlisterBulmanがいくつかのコードで更新されました – pierdevara

+0

問題は1つのBeanstalkdサーバーでも発生しますか?すべてのサーバがバイナリロギングなどのために異なる設定を持っていますが、なぜ複数の設定を使用するのですか? –

答えて

0

問題は、私のコードのprocess_jobビット内起こっTCP切断しました。 pheanstalkオブジェクトは、実行チェーンのどこかで上書きされます。

私は、putコマンドを送信する前にemptiest beanstalkdサーバーが使用可能であるかどうかをチェックするライブラリラッピングpheanstalkを持っています。次に、最高のサーバーの詳細を持つ新しいPheanstalkインスタンスを作成し、現在の接続として保存して、コマンドをディスパッチします。

作業員がサブジョブをキューに送信することがあります。ライブラリは最初にワーカーにロードされ、ジョブをフェッチし、再びprocess_jobでキューに送信されます。 Codeigniterの依存性注入のために、そのライブラリは同じオブジェクトを参照し、process_jobの内部ではワーカーの現在の接続を上書きしてTCP切断を引き起こします。

関連する問題