最近在使用JQroups做多用户的组播通信程序,发现当超过两个用户连接上的时候,会出现如下错误:
2000ms出现后不一会,所有终端都会全部退出广播
如下打印日志信息:
failed to collect all acks (expected=1) for view
after 2000ms missing acks from -
我的协议配置主体如下:
<UDP ip_mcast="true"
...../>
<FD timeout=”3000” max_tries=”1”/>
这么配置的初衷是:
1.使用组播进行消息的传递,减少网络的数据量。
2.同时,能够及时的对成员的断开做判断。(其实Jgroups也有默认检测时间,大约是35秒)
但是,这么配置的话,就会出现以上的错误信息。
经过多次尝试,下面是我总结的一个表格:
是否使用UDP协议
是否使用多播
是否增加FD检测
是否发生掉线
成员断线判断是否及时
是
否
否
否
否
是
否
是
否
是
是
是
否
否
否
是
是
是
是
未知(因为掉线了)
也就是说:只有同时使用多播和FD检测的时候,才会出现掉线这样的情况。
如何解决这个问题呢?
阅读官方文档,官网推荐使用多个通道来实现不同的操作。
根据以上表格和上面列出来的2点需求来看,我们这边也可以这么做:
1.创建一个通道(online),专门用于检测成员是否掉线。
2.创建一个通道(command),专门用于发送命令和传输数据。
这样的话,
1. online的配置可以这样设计:不使用多播,但是增加FD检测。
不使用多播也不会增加数据量,因为这个通道上不会发送数据,只会做掉线的判断。
增加FD检测,就能够及时的知道是否已经掉线。
所以,online配置文件类似于
<UDP ip_mcast="false"
....../>
<FD timeout="2000" max_tries = "1"/>
2.command的配置文件可以这样设计:使用多播,但不增加FD检测。
使用多播,可以减少网络数据量,降低网络阻塞的可能性。
不用FD检测,因为FD检测在online中专门进行了。
所以,command配置文件类似于:
<UDP ip_mcast="true"
...../>
<FD /> <!-- 无需设置-->
这两个通道配合工作:
每次连接时,同时启动online和command通道。
比如说有这样一个场景(虽然这个场景不是很常见):一个服务器A,一个服务器B,N个成员。N个成员的活动依赖服务器B的状态,如果服务器B宕机了,N个成员就也应该终止活动。服务器A,B和成员,都在同一个网络中。
在服务器B掉线的场景下:只要服务器A的online通道检测到服务器B掉线了,服务器A就通过command通道发送命令给其他成员,其他成员接收到命令之后,关闭和服务器B连接的online通道和 command通道。等待下次的连接。