2

ローカル コンピューターとリモート サーバーの間に zeromq を使用して単純な「パイプライン」をセットアップしようとしています。ローカル コンピューターでスクリプトをテストしたところ、問題なく動作しましたが、最後にリモート コンピューター (SOCKET_PULL を使用するコンピューター) を使用しようとすると、問題が発生し始めました。どのプロセスから送信された最初のメッセージも、常に失われていました。

コードはシンプルで、

プッシュ (sender.php):

<?php
//Use the specified port or 5555 for sending jobs
$port = $_SERVER['argc'] > 1 ? $_SERVER['argv'][1] : '5555';
$jobN = $_SERVER['argc'] > 2 ? $_SERVER['argv'][2] : '';


$context = new ZMQContext();

//  Socket to send messages on
$sender = new ZMQSocket($context, ZMQ::SOCKET_PUSH);

//If I want to connect to the server I use this line
$sender->connect("tcp://my-server-address.com:$port");

//If I want to connect to localhost I use this line
//$sender->connect("tcp://localhost:$port");

$sender->send('job-1' . ($jobN ? " $jobN" : ''));
$sender->send('job-2' . ($jobN ? " $jobN" : ''));
$sender->send('job-3' . ($jobN ? " $jobN" : ''));
$sender->send('job-4' . ($jobN ? " $jobN" : ''));
$sender->send('job-5' . ($jobN ? " $jobN" : ''));
$sender->send('job-6' . ($jobN ? " $jobN" : ''));
$sender->send('job-7' . ($jobN ? " $jobN" : ''));
$sender->send('job-8' . ($jobN ? " $jobN" : ''));
$sender->send('job-9' . ($jobN ? " $jobN" : ''));
$sender->send('job-10' . ($jobN ? " $jobN" : ''));
echo 'done';

レシーバー (worker.php)

<?php
//Use the specified port or 5556 for getting finished jobs
$port = $_SERVER['argc'] > 1 ? $_SERVER['argv'][1] : '5555';

//  Prepare our context and socket
$context = new ZMQContext();
$receiver = new ZMQSocket($context, ZMQ::SOCKET_PULL);
$receiver->bind("tcp://*:$port");

$count = 1;
while(true) {
    $string = $receiver->recv();
    echo "Received $string $count\n";
    $count += 1;
}

ローカルでコードを実行すると(ある端末では「php worker.php」、別の端末では「php sender.php」)。

私は得る

Received job-1 1
Received job-2 2
Received job-3 3
Received job-4 4
Received job-5 5
Received job-6 6
Received job-7 7
Received job-8 8
Received job-9 9
Received job-10 10

しかし、リモートを使用すると(送信者はミューローカル、受信者はリモート)、

Received job-2 1
Received job-3 2
Received job-4 3
Received job-5 4
Received job-6 5
Received job-7 6
Received job-8 7
Received job-9 8
Received job-10 9

私は何か間違ったことをしていますか??


注: 送信者をロックすることはできません (そして、SOCKET_REQ は応答を待っている実行をロックします)。とにかく、0mq はロックなしで動作するはずです。注:私のローカルはMacコンピューターで、サーバーはubuntuを使用したAmazonインスタンスです(影響はないと思いますが、影響がある場合に備えて書いています)。


編集: 明確にするために、インターネットを介してデータを送信したくありません。この問題が発生したときに、待ち時間の長い zeromq をテストしたかっただけです。

4

2 に答える 2

7

The problem is what Pieter's documentation calls the "slow joiner". This is misnamed because it implies it's the subscriber/listener is the root of the problem. This is not the case.

The problem is most likely on the publisher side. You are sending your message before the publisher is connected.

How can this be? zmq_connect or zmq_bind returns so you must be ready. No, you are not.

Apparently the connection/publishing setup is not complete when the connect/bind returns. The connection is finished some time after the function returns.

So how do you solve the problem? The easy way is to wait. The problem with this is you don't know how long to wait and the actual time depends on the particular network situation and the hardware involved.

A better way, but more involved, is to set up a local subscriber for your publisher address and repeatedly publish an administrative message which once received lets you know you are up and ready.

于 2013-03-02T14:41:02.847 に答える
4

問題を解決しました。ローカルとサーバーに異なるバージョンの zeromq をインストールしました。同じエラーが発生する場合は、バージョンを確認してください。

注: Zeromq はインターネットで動作します。唯一のこと (少なくとも php では) は、プロセスを閉じる前にメッセージが完全に送信されたことを確認する必要があることです。私のテストでは、ランダムなサイズ (平均サイズ: 1MB) の 75000 件のメッセージを異なるコンピューター間で数回送信し、すべてのメッセージを期待どおりに受信しました。

于 2012-07-25T16:59:41.897 に答える