如何保护ZeroMQ请求回复模式以防止潜在的消息丢失? [英] How to protect ZeroMQ Request Reply pattern against potential drops of messages?
问题描述
我正在尝试在 c#应用程序和分布式 python 服务器之间的TCP层上实现 ZeroMQ 模式.我有一个使用请求-回复 REQ/REP
模式的版本,在 localhost
上进行测试时,它似乎相对稳定.但是,在测试中,我调试了一些情况,在接收到明显不可接受的回复之前,我不小心发送了多个请求.
在实践中,网络可能会丢掉很多数据包,我怀疑我会丢掉很多答复和/或无法发送请求.
1)是否可以重置REQ/REP
请求-应答套接字之间的连接?
使用REOUTER/DEALER
模式更有意义吗?因为这是我使用ZeroMQ的第一个应用程序,所以我希望保持它的简单性.
2)是否存在用于处理连接事件的良好的ZeroMQ机制?我一直在阅读指南",其中提到了一些监视连接的内容,但没有示例.我找到了 ZMonitor
,但是无法在c#中触发事件.
广告1)否,
没有暴露给用户的套接字链接管理界面来测试/重置状态ZeroMQ框架中从FSA到FSA的链接.
是的, XREQ/XREP
可以帮助您克服僵局,这可能&确实发生在REQ/REP
可扩展的正式沟通模式中:
引用:
REQ/REP
死锁>>> https://stackoverflow.com/a/38163015/3666197
Fig.1:
为什么在[1]
in_WaitToRecvSTATE_W2R
的所有情况下都使用朴素的 REQ/REP
是错误的+ [2]
in_WaitToRecvSTATE_W2R
主要是REQ-FSA/REP-FSA
有限状态自动机的不可挽回的相互僵局,并且永远不会到达内部的下一个" in_WaitToSendSTATE_W2S
状态.
XTRN_RISK_OF_FSA_DEADLOCKED ~ { NETWORK_LoS
: || NETWORK_LoM
: || SIG_KILL( App2 )
: || ...
: }
:
[App1] ![ZeroMQ] : [ZeroMQ] ![App2]
code-control! code-control : [code-control ! code-control
+===========!=======================+ : +=====================!===========+
| ! ZMQ | : | ZMQ ! |
| ! REQ-FSA | : | REP-FSA! |
| !+------+BUF> .connect()| v |.bind() +BUF>------+! |
| !|W2S |___|>tcp:>---------[*]-----(tcp:)--|___|W2R |! |
| .send()>-o--->|___| | | |___|-o---->.recv() |
| ___/ !| ^ | |___| | | |___| ^ | |! \___ |
| REQ !| | v |___| | | |___| | v |! REP |
| \___.recv()<----o-|___| | | |___|<---o-<.send()___/ |
| !| W2R|___| | | |___| W2S|! |
| !+------<BUF+ | | <BUF+------+! |
| ! | | ! |
| ! ZMQ | | ZMQ ! |
| ! REQ-FSA | | REP-FSA ! |
~~~~~~~~~~~~~ DEADLOCKED in W2R ~~~~~~~~ * ~~~~~~ DEADLOCKED in W2R ~~~~~~~~~~~~~
| ! /\/\/\/\/\/\/\/\/\/\/\| |/\/\/\/\/\/\/\/\/\/\/! |
| ! \/\/\/\/\/\/\/\/\/\/\/| |\/\/\/\/\/\/\/\/\/\/\! |
+===========!=======================+ +=====================!===========+
Fig.2:
人们可以使用几个纯ZeroMQ
内置插件来实现自由步进传输层,并添加一些SIG层工具以完全控制所有可能的分布式系统状态.>
App1.PULL.recv( ZMQ.NOBLOCK )
和 App1.PULL.poll( 0 )
很明显
[App1] ![ZeroMQ]
code-control! code-control
+===========!=======================+
| ! |
| !+----------+ |
| .poll()| W2R ___|.bind() |
| ____.recv()<----o-|___|-(tcp:)--------O
| PULL !| |___| | :
| !| |___| | :
| !| |___| | :
| !+------<BUF+ | :
| ! | : ![App2]
| ! | : [ZeroMQ] ! code-control
| ! | : [code-control ! once gets started ...
| ! | : +=====================!===========+
| ! | : | ! |
| ! | : | +----------+! |
| ! | : | |___ |! |
| ! | : | |___| <--o-<.send()____ |
| ! | :<<-------<tcp:<|___| W2S|! PUSH |
| ! | : .connect() <BUF+------+! |
| ! | : | ! |
| ! | : | ! |
+===========!=======================+ : +=====================!===========+
广告2)否,
,但是可以创建自己的"ZeroMQ消耗品" ,以测试分布式系统设置新的传输/信令套接字的能力,准备好处置它,如果RTO测试未能证明双方都准备好通过ZeroMQ基础设施进行设置并进行通信(请注意,问题不仅出在ZeroMQ上,层,但应用程序端也不必处于就绪状态/处于这种状态以处理预期的通信交互(并可能导致软锁/死锁).
下一步最好?
我现在对您的其他问题所能做的就是引导您看到有关此主题的更大图片>> > ,其中包含更多参数,简单的信号平面/消息传递平面插图和指向必读书籍的直接链接来自Pieter HINTJENS.
I'm trying to implement a ZeroMQ pattern on the TCP layer between a c# application and distributed python servers. I've gotten a version working with the request-reply REQ/REP
pattern and it seems relatively stable when testing on localhost
. However, in testing, I've debugged a few situations, where I accidently send multiple requests before receiving a reply which apparently is not acceptable.
In practice the network will likely have lots of dropped packets and I suspect that I'll be dropping lots of replies and/or unable to send requests.
1) Is there a way to reset the connection between REQ/REP
request-reply sockets?
Would a REOUTER/DEALER
pattern instead make more sense? As this is my first application with ZeroMQ, I was hoping to keep it simple.
2) Is there a good ZeroMQ mechanism for handling the connectivity events? I've been reading "the guide" and there are a few mentions of monitoring connections, but no examples. I found the ZMonitor
, but can't get the events to trigger in c#.
Ad 1) No,
there is not any socket link-management interface exposed to user to test/reset the state of the FSA-to-FSA link in ZeroMQ framework.
Yes, XREQ/XREP
may help you overcome the deadlocks, that may & do happen in REQ/REP
Scaleable Formal Communication Pattern:
Ref.:
REQ/REP
Deadlocks >>> https://stackoverflow.com/a/38163015/3666197
Fig.1:
Why it is wrong to use a naive REQ/REP
all cases when [1]
in_WaitToRecvSTATE_W2R
+ [2]
in_WaitToRecvSTATE_W2R
are principally unsalvageable mutual deadlock of REQ-FSA/REP-FSA
Finite-State-Automata and will never reach the "next" in_WaitToSendSTATE_W2S
internal state.
XTRN_RISK_OF_FSA_DEADLOCKED ~ { NETWORK_LoS
: || NETWORK_LoM
: || SIG_KILL( App2 )
: || ...
: }
:
[App1] ![ZeroMQ] : [ZeroMQ] ![App2]
code-control! code-control : [code-control ! code-control
+===========!=======================+ : +=====================!===========+
| ! ZMQ | : | ZMQ ! |
| ! REQ-FSA | : | REP-FSA! |
| !+------+BUF> .connect()| v |.bind() +BUF>------+! |
| !|W2S |___|>tcp:>---------[*]-----(tcp:)--|___|W2R |! |
| .send()>-o--->|___| | | |___|-o---->.recv() |
| ___/ !| ^ | |___| | | |___| ^ | |! \___ |
| REQ !| | v |___| | | |___| | v |! REP |
| \___.recv()<----o-|___| | | |___|<---o-<.send()___/ |
| !| W2R|___| | | |___| W2S|! |
| !+------<BUF+ | | <BUF+------+! |
| ! | | ! |
| ! ZMQ | | ZMQ ! |
| ! REQ-FSA | | REP-FSA ! |
~~~~~~~~~~~~~ DEADLOCKED in W2R ~~~~~~~~ * ~~~~~~ DEADLOCKED in W2R ~~~~~~~~~~~~~
| ! /\/\/\/\/\/\/\/\/\/\/\| |/\/\/\/\/\/\/\/\/\/\/! |
| ! \/\/\/\/\/\/\/\/\/\/\/| |\/\/\/\/\/\/\/\/\/\/\! |
+===========!=======================+ +=====================!===========+
Fig.2:
One may implement a free-stepping transmission layer using several pure ZeroMQ
builtins and add some SIG-layer tools for getting a full control of all possible distributed system states.
App1.PULL.recv( ZMQ.NOBLOCK )
and App1.PULL.poll( 0 )
are obvious
[App1] ![ZeroMQ]
code-control! code-control
+===========!=======================+
| ! |
| !+----------+ |
| .poll()| W2R ___|.bind() |
| ____.recv()<----o-|___|-(tcp:)--------O
| PULL !| |___| | :
| !| |___| | :
| !| |___| | :
| !+------<BUF+ | :
| ! | : ![App2]
| ! | : [ZeroMQ] ! code-control
| ! | : [code-control ! once gets started ...
| ! | : +=====================!===========+
| ! | : | ! |
| ! | : | +----------+! |
| ! | : | |___ |! |
| ! | : | |___| <--o-<.send()____ |
| ! | :<<-------<tcp:<|___| W2S|! PUSH |
| ! | : .connect() <BUF+------+! |
| ! | : | ! |
| ! | : | ! |
+===========!=======================+ : +=====================!===========+
Ad 2) No,
but one may create one's own "ZeroMQ-consumables" to test the distributed system's ability to setup a new transport/signalling socket, being ready to dispose it, if the RTO-test fails to prove that both ( multiple ) sides are ready to setup + communicate over the ZeroMQ infrastructure ( notice, that the problems are not only with the ZeroMQ layer, but also the App-side need not be ready/in such a state to handle the expected communication interactions ( and may cause soft-locks / dead-locks ).
The best next step?
What I can do for your further questions right now is to direct you to see a bigger picture on this subject >>> with more arguments, a simple signalling-plane / messaging-plane illustration and a direct link to a must-read book from Pieter HINTJENS.
这篇关于如何保护ZeroMQ请求回复模式以防止潜在的消息丢失?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!