一个控制系统,发送端发送指令,接收端(不是自研,可能是 x86 ,可能是 plc ,pxi 设备等)接收指令。想问一下,在接收端做不到有能力处理重复消息或保证消息幂等的情况下,是不是无法同时保证这个消息的:

可靠性,消息不丢
及时送达, 消息第一时间被送达响应。

ack

参考 mqtt

消息的可靠性就是靠重复率来保证的。如果客户端做不到处理重复消息,就没办法保证消息的可靠性。换个方案,要不提高客户端的配置,要不就放弃消息的可靠性。

ack 没收到,不代表接收端没收到,然后不能处理重复消息。。

同意你的看法。

参考下 TCP ,可以解决重发的问题,只能类似于建立连接的方式,然后确保 syn

你要说把“啥都做不到”作为前提,那就别指望解决问题了

TCP 协议本身就是可靠的。UDP 你要本地测一下丢包率,如果局域网网线对接,丢包率小于 0.0000001%,那也可以近似看成是可靠的。

被控端类型太多,而且由不同供应商组成。没办法做统一约束

意思是重复问题交给协议栈解决,业务只要发一次就可以了么

#9 你这个是使用场景不匹配的问题吧,plc ,pxi 设备之所以这么设计协议估计就首先约定控制端在同一物理位置且通过可靠忘了连接,你非要弄到公网或者弱网下用,不单独添加设备侧得本地网关保证可靠性,显然是不能的吧

“接收端做不到有能力处理重复消息或保证消息幂等”换个表述方式,意思是不是"接收端只接收,不响应"?很多工控系统是这样设计的,设计的时候就没有“协议”这个概念,接收端“无脑”执行所有指令,默认输入信令永远正确且实时。(因为它可能就是一台单独的设备,从来没考虑过远程控制)即使有响应,也不代表能正确处理“重复”指令。很多“响应”的意思是收到指令而已,并不代表指令的执行结果。(因为这类工控系统的指令执行结果是肉眼可见的)

"TCP 协议本身就是可靠的",不代表指令是可靠的.存在接收到消息但是没有执行的情况.

那和发送端无关,发送端能保证的就是在协议允许的情况下保证对方收到了。收到和执行是两个事情。

"接收端只接收,不响应"? 是有回令的。但是回令其实是个单独的信号,还有可能是总线的。指令执行的结果到是不用太管,正确错误都无所谓。所以我要保证的是,这条指令发了,然后收到了。

不是在公网或弱网下啊。就是本地内网,但是可靠性要求实在是太高了。

GPT4 的回答:在您描述的场景中,如果接收端不能处理重复的消息或保证消息的幂等性,同时保证消息的可靠性(不丢失消息)和及时性(快速送达)确实是一个挑战。这主要是因为在大多数消息队列系统中,为了保证消息的可靠性,通常会采用至少一次( at-least-once )或者精确一次( exactly-once )的消息传递语义:1. 至少一次( At-least-once ):保证消息至少被传递一次,但可能会导致消息重复。在这种情况下,接收端需要能够处理重复消息或实现消息的幂等性。2. 精确一次( Exactly-once ):保证每个消息只被传递一次。这是最理想的,但也是最难实现的,因为它需要在发送端、消息队列系统和接收端之间进行复杂的协调。3. 最多一次( At-most-once ):消息可能会丢失,但不会重复传递。在您的情况下,由于接收端不能处理重复的消息或实现幂等性,您可能需要采用以下策略:- 使用可靠的消息传递机制:选择一个支持至少一次或精确一次传递语义的消息队列系统,如 Kafka 的精确一次语义或 RabbitMQ 的消息确认机制。- 减少消息重复的可能性:虽然接收端不能处理重复消息,但可以通过减少网络问题、提高发送端和消息队列系统的可靠性来降低消息重复的风险。- 使用超时和重试机制:在发送端实现超时和重试逻辑,如果在预定时间内未收到确认,可以重发消息。这提高了消息送达的可靠性,但可能增加重复消息的风险。- 外部协调:如果可能,可以在系统外部实现一种机制来跟踪消息的状态,并在消息重复时协助接收端处理。- 消息唯一标识:在消息中包含唯一标识符,并在接收端实现一定程度的逻辑来检测重复的消息,即使不能完全处理它们,也能至少识别出它们。需要注意的是,即便采用了上述策略,如果接收端完全无法处理重复消息,那么在网络不稳定或系统出现故障时,仍然可能面临挑战。在这种情况下,可能需要重新考虑系统的设计,或者在接收端实现一些基本的幂等性处理逻辑。

两军问题

人家要求的是控制消息可靠啊,tcp 可靠有什么用.

假设不可靠,然后根据不可靠来考虑怎么确保能执行。物联网这块不是很多的么?

wamp-proto.org/

也不一定无办法解决,主要是看发送端和接收端是用什么协议栈。如果是标准 TCP 的话还有点戏