如何保护 ZeroMQ 请求回复模式免受潜在的消息丢失?
How to protect ZeroMQ Request Reply pattern against potential drops of messages?
我正在尝试在 c# 应用程序和分布式 [ 之间的 TCP 层上实现 ZeroMQ 模式=46=] 个服务器。我有一个使用请求-回复 REQ/REP
模式的版本,在 localhost
[=34= 上测试时它似乎相对稳定].但是,在测试中,我调试了一些情况,在这些情况下,我在收到显然不可接受的回复之前不小心发送了多个请求。
在实践中,网络可能会丢弃很多数据包,我怀疑我会丢弃很多无法发送请求的回复and/or。
1) 有没有办法重置 REQ/REP
请求-回复 套接字之间的连接?
REOUTER/DEALER
模式会更有意义吗?因为这是我使用 ZeroMQ 的第一个应用程序,所以我希望保持简单。
2) 是否有一个好的 ZeroMQ 机制来处理连接事件? 我一直在阅读 "the guide" 并且有一些关于监控连接的提及,但是没有例子。我找到了 ZMonitor
,但无法在 c# 中触发事件。
Ad 1) No,
没有任何socket link-管理接口暴露给用户test/reset的状态ZeroMQ 框架中的 FSA-to-FSA link。
是的,XREQ/XREP
可能会帮助您克服僵局,这在 REQ/REP
可扩展的正式沟通模式中可能并且确实会发生:
Ref.: REQ/REP
Deadlocks >>>
Fig.1:
为什么使用幼稚是错误的REQ/REP
所有情况当 [1]
in_WaitToRecvSTATE_W2R
+ [2]
in_WaitToRecvSTATE_W2R
基本上无法挽救REQ-FSA/REP-FSA
有限状态自动机的相互死锁,永远不会达到 "next" 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-consumables" 来测试分布式系统设置新 transport/signalling 套接字的能力,准备好处理它,如果 RTO 测试未能证明双方(多)方已准备好通过 ZeroMQ 基础设施设置+通信(注意,问题不仅出在 ZeroMQ 层,应用端也不需要 ready/in 这样的状态来处理预期的通信交互(并且可能导致软锁/死机-锁)。
最好的下一步是什么?
What I can do for your further questions right now is to direct you to see a bigger picture on this subject >>> 更多参数,一个简单的信号平面/消息平面图和一个直接 link 阅读 Pieter HINTJENS 的必读书籍。
我正在尝试在 c# 应用程序和分布式 [ 之间的 TCP 层上实现 ZeroMQ 模式=46=] 个服务器。我有一个使用请求-回复 REQ/REP
模式的版本,在 localhost
[=34= 上测试时它似乎相对稳定].但是,在测试中,我调试了一些情况,在这些情况下,我在收到显然不可接受的回复之前不小心发送了多个请求。
在实践中,网络可能会丢弃很多数据包,我怀疑我会丢弃很多无法发送请求的回复and/or。
1) 有没有办法重置 REQ/REP
请求-回复 套接字之间的连接?
REOUTER/DEALER
模式会更有意义吗?因为这是我使用 ZeroMQ 的第一个应用程序,所以我希望保持简单。
2) 是否有一个好的 ZeroMQ 机制来处理连接事件? 我一直在阅读 "the guide" 并且有一些关于监控连接的提及,但是没有例子。我找到了 ZMonitor
,但无法在 c# 中触发事件。
Ad 1) No,
没有任何socket link-管理接口暴露给用户test/reset的状态ZeroMQ 框架中的 FSA-to-FSA link。
是的,XREQ/XREP
可能会帮助您克服僵局,这在 REQ/REP
可扩展的正式沟通模式中可能并且确实会发生:
Ref.:
REQ/REP
Deadlocks >>>
Fig.1:
为什么使用幼稚是错误的REQ/REP
所有情况当 [1]
in_WaitToRecvSTATE_W2R
+ [2]
in_WaitToRecvSTATE_W2R
基本上无法挽救REQ-FSA/REP-FSA
有限状态自动机的相互死锁,永远不会达到 "next" 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-consumables" 来测试分布式系统设置新 transport/signalling 套接字的能力,准备好处理它,如果 RTO 测试未能证明双方(多)方已准备好通过 ZeroMQ 基础设施设置+通信(注意,问题不仅出在 ZeroMQ 层,应用端也不需要 ready/in 这样的状态来处理预期的通信交互(并且可能导致软锁/死机-锁)。
最好的下一步是什么?
What I can do for your further questions right now is to direct you to see a bigger picture on this subject >>> 更多参数,一个简单的信号平面/消息平面图和一个直接 link 阅读 Pieter HINTJENS 的必读书籍。