我有一个系统通过TCP套接字使用Java向外部系统发送消息。如果我们想尽力确保收到已发送的消息,我们是否需要执行重试逻辑以防发送方法中出现网络故障?
在我看来,没有必要重试,因为它已经由TCP处理。这个论点有效吗?
谢谢!
Bo
答案 0 :(得分:2)
了解TCP是传输协议非常重要。它的目的是在机器之间设置可靠的数据流,而不是在应用程序之间。成功的send
并不意味着消息已经传递,这意味着您的内核已将消息排队并将很快发送。当主机收到消息并对其进行确认时,并不意味着您的应用程序已经呼叫或将调用recv
并实际获取数据。
因此,您当然可以依赖套接字错误来检测断开的连接。但是当连接中断时,您的应用程序将无法确定交付的内容以及不仅仅基于您可以从TCP获得的信息的内容。
您为程序开发的应用程序级协议因此需要它自己的跟踪应用程序之间成功交付的机制。重新连接和重试机制将成为其中的一部分。
Alice通过TCP向Bob发送包含其状态更新的数据包。在某些时候,Alice有三个要发送的更新。 Alice的send
电话成功。
第一次更新由Bob recv
编辑。第二次更新是由他的机器接收的,但是在Bob第二次呼叫recv
之前,机器突然重启。
鲍勃办公室的一些安全中间设备放弃了第三次更新。
Alice希望再发送一次更新。连接已处于错误状态,因此send
失败。
此时Alice已发送三次更新,但Bob只收到一次。当Bob的机器重新联机并建立新连接时,Alice和Bob需要在进一步继续之前同步其状态。他们需要同步,因为Alice实际上并不知道Bob能够处理多少更新。仅基于TCP,她可能只会对Bob的机器已经收到多少更新进行有根据的猜测。