1

オフロード処理に使用されていた Web アプリケーションとスレーブ アプリケーションの間でメッセージを交換する目的で、ZeroMQ の要求/応答ソケットを使用してきました。いくつかのケースで、送信されたすべての ZMQ メッセージが実際に相手側で受信されたわけではないことに気付きました。かなり信頼できると私が思っていたIPCプロトコルでさえ、これが起こるのは奇妙なことです。

エラーを生成せずに、送信されたメッセージが配信されない原因は何ですか?

クライアント コードの例を次に示します。

# ironic
class ReliableClient(object):
    def _reconnect(self):
        if self.socket:
            self.socket.close()
            self.socket = None

        self.socket = self.context.socket(zmq.REQ)
        self.socket.connect(self.server_url)

        # Give the server 2 sec to respond
        self.socket.RCVTIMEO = 2000
        self.socket.SNDTIMEO = 2000

        self.socket.LINGER = 3

    def __init__(self, server_url=None, server_name=None):
        self.socket = None
        self.server_url = server_url

        if server_name is None:
            self.server_name = server_url
        else:
            self.server_name  = server_name

        self.lock = threading.Lock()
        self.context = zmq.Context()

        self._reconnect()

    def msg(self, msg):
        raw_out = dumps(msg)

        # send
        self.lock.acquire()
        try:
            self.socket.send(
                raw_out,
                copy=True
            )
        except zmq.ZMQError as ex:
            log.exception(ex, '%s: failed to send', self.server_name)
            self.lock.release()
            raise CommunicationError('failed to send')

        # receive
        try:
            raw_in = self.socket.recv()
        except zmq.ZMQError as ex:
            log.exception(ex, '%s: failed to receive', self.server_name)
            raise CommunicationError('failed to receive')
        finally:
            self.lock.release()

        msg_in = loads(raw_in)  

        return msg_in
4

3 に答える 3

3

私は IPC プロトコルには詳しくありませんが、ZMQ/TCP を幅広く扱ってきました。

TCP を介した最も単純な ZMQ REQ/REP パターンでさえ、適切に使用していればメッセージがドロップされることはありません。ネットワーク接続またはリモート エンドポイントがダウンした場合、無期限にハングする可能性がありますが、サイレントに失敗することはありません。特定の状況でメッセージをドロップするように設計された特定のソケットがあります。たとえば、HWM に達したときにメッセージをドロップするものもあります。

于 2013-08-15T17:59:34.917 に答える
2

エラーを生成せずに、送信されたメッセージが配信されない原因は何ですか?

ROUTERサーバーから zmq ワーカー プロセスへのメッセージを仲介するためにソケットを使用している場合、 ROUTERs はデフォルトで、配信できない送信メッセージをドロップします。「お届けできません」とは?ROUTER は、クライアント ID からクライアント接続への内部マッピングを維持します。ルーター上のすべてのメッセージには、クライアントによって提供されるか、ルーターによって自動割り当てされる ID があるため、対応する接続​​がないアウトバウンド メッセージはすべて、ルートは、静かにドロップされます。

配信不能メッセージを報告するよう ROUTER に指示することで、このシナリオがいつ発生するかを特定できます。つまり、ROUTER は、メッセージを配信できない場合にエラーを生成します。Javaでは、メソッドはrouterSocket.setRouterMandatory(true)です。これに対応するpythonを見つけるだけです(私はpyガイではありません、笑)

ROUTER がメッセージをドロップしていると判断した場合、問題はなぜでしょうか? 私の場合、異なるスレッドでサーバーメッセージを送受信するzmqクライアントがあり、受信スレッドはサーバーからの最初の「OK」応答に十分な速さで接続されていなかったため、単にタイミングの問題でした.クライアント。

それが役立つことを願っています

于 2013-08-14T19:31:56.073 に答える