Разъем ZMQ - отключить, когда все запросы обслуживаются
Я пытаюсь реализовать ZMQ REQ/REP
модель на Java
У меня есть серверная роль, работающая на посте 5564, который действует как Replier
ZMQ.Socket repSock = context.socket(ZMQ.REP);
У меня есть Клиент- роль, работающая на пост 5563
ZMQ.Socket syncclient = context.socket(ZMQ.REQ);
У меня есть прокси- сервер в середине, который передает запрос и ответ
ZMQ.proxy(reqSocket, repSocket, null);
Хорошая вещь о наличии прокси, я могу добавить несколько серверов
repSocket.connect("tcp://" + addr.getHostAddress() + ":" + port);
Который работает нормально.
Теперь, когда я удаляю узел сервера из прокси
repSocket.disconnect("tcp://" + addr.getHostAddress() + ":" + port);
Клиент застревает, так как запрос сделан и REQ
Сокет ждет ответа.
Таким образом, процесс застрял на syncclient.recvStr()
for (int request_nbr = 0; request_nbr < (request_nbr + 1); request_nbr++) {
syncclient.send(str.getBytes(),0);
System.out.println("Send Dataaaa....... " );
String data = syncclient.recvStr(Charset.defaultCharset());
System.out.println(" here.. " +data);
request_nbr++;
}
Я искал и не мог найти способ отследить REQ
-разъем
Мне нужна любая из двух вещей:
Способ следить за
Socket
-экземпляр, который я собираюсь отключить, дождаться обработки всех сообщений, чтобыsyncclient.recvStr()
не будет заблокированСпособ сброса
syncclient
-гнездо, так что я могу продолжать получатьREQ/REP
отвечать без перерыва
1 ответ
В реальных сценариях лучше избегать использования режима блокировки ZeroMQ .send()
/ .recv()
методы и лучше использовать .poll()
,
Хотя для этого может потребоваться немного больше SLOC-кода, результаты оставляют вас в элементе управления, тогда как блокирующий SLOC-элемент берет весь элемент управления из вашего кода, и вы не можете ничего с этим поделать до тех пор, пока (если вообще) не будет доставлено следующее сообщение. Это очень неправильная практика проектирования, за исключением самых упрощенных примеров из учебников, которые на самом деле являются своего рода антишаблонами для реального мира.
Таким образом, не ожидайте, что Вопрос 2 будет каким-то волшебным образом решен, это не часть API ZeroMQ (по многим довольно громким евангелизированным причинам). Лучше выбрать между .setsockopt( ZMQ.REQ_RELAXED, 1 )
, если версия API и контекст использования разрешают, или не используют тривиальный REQ/REP
паттерн вообще (из-за его известного риска попасть в непреодолимую взаимную тупиковую ситуацию (см. другие мои посты на эту самую тему, где этот феномен был иллюстрирован и объяснен бесчисленное количество раз)).
Аналогичным образом, задание Вопроса 1 кажется разумным в тех случаях, когда вы никогда не читали спецификации и / или документацию ZeroMQ, а также "Best Practices" ZeroMQ. Потратив некоторое время в этом, ваши варианты будут кристально чистыми. Нет таких инструментов для этого встроенного. Можно добавить какое-то дополнение, если нужно добавить какую-то неосновную логику для ее / его собственной необходимости. Единственный параметр, который косвенно влияет на поведение aSocket.close()
доступно в .setsockopt( ZMQ.LINGER, 0 )
, что может помочь предотвратить переход системы в эффективное состояние зависания, один раз aSocket
бесконечно ждет состояния, которое никогда не произойдет в тех случаях, когда очередь сообщений все еще не пуста (сообщения все еще ожидают доставки).
Переход к дизайну распределенных систем - это все равно, что войти в новый мир. Никакие последовательности не гарантированы (не последовательные пути выполнения кода). Никаких средств какого-либо локального контроля над удаленными объектами, их состояниями, их сбоями, их присутствием вообще, их действительной версией ZeroMQ API.
Действительно сложный мир для вступления.
Nb:
Возможно, вы уже знаете, что можно .connect()
aSocket
-экземпляр (лучше точка доступа к aSocket
-instance) для более чем одного удаленного конца без использования прокси. С некоторыми дополнительными .setsockopt()
настройка ZMQ.IMMEDIATE
значение 1 поможет лучше управлять политикой циклического распределения независимо от транспортных классов, используемых для фактической доставки сообщений ({ tcp:// | ipc:// | vmci:// | pgm:// | epgm:// | inproc:// }
). Все это в ваших руках.