需要解决双主机组的 JGroups 非分组行为
Need to solve JGroups non-grouping behavior for a two-host group
我正在使用 JGroups 通过让两台机器加入同名组来创建一个集群,但我的分组行为不稳定,我想问是否有 JGroups 配置更改或我需要更改服务器配置才能使其正常工作。
当我在 JGroups 组中有两个主机时,一个成员离开,另一个成员在 viewAccepted 中观察到这一点。但是当较早的成员 returns 时,他们在 viewAccepted 函数中都看不到对方,并且他们 运行 在有效独立的组中(不好)。这种非分组行为可以是随机的。比如我昨天下午5点断开了一台主机,今天早上重启了一台主机,群里都没看到另一台。然而,一旦我停止他们两个并重新启动,他们在组中找到了对方。
JGroups 的最终用途是将两个 Tomcat 主机 运行 连接到同一个应用程序,这样集群中列出的第一台主机 运行s 报告,而第二台等待第一个死去,然后接替第一个宿主的位置和 运行 的报告。当第一台主机恢复服务时,它成为集群成员列表中的第二台,并等待另一台主机死亡。现在应用程序的行为与下面的测试程序的行为相呼应。
使用开箱即用的 JGroups jgroups-4.1.6.Final.jar,没有自定义 udp.xml 文件,也没有新 JChannel() 的参数。我有一个测试应用程序 运行s 在两个 RHEL 7 主机上让它们集群。代码如下:
import java.util.List;
import org.jgroups.Address;
import org.jgroups.JChannel;
import org.jgroups.Message;
import org.jgroups.Receiver;
import org.jgroups.View;
public class ClusterTest implements Receiver {
private String clusterName;
private JChannel channel;
public ClusterTest(String[] args) {
if (args.length > 0) {
clusterName = args[0];
} else {
clusterName = "TEST_CLUSTER";
}
}
/**
* Joins the JGroups cluster
*/
private void joinCluster() {
System.out.println("joinCluster(): joining cluster \"" + clusterName + "\"");
try {
channel = new JChannel();
channel.setReceiver(this);
channel.connect(clusterName);
} catch (Exception e) {
System.out.print("joinCluster failed: ");
e.printStackTrace();
}
}
@Override
public void viewAccepted(View view) {
System.out.println("viewAccepted(): view = \"" + view + "\" for name = \"" + channel.getName() + "\" / \"" + channel.clusterName() + "\"");
List<Address> viewMembers = view.getMembers();
int memNum = 0;
for (Address member : viewMembers) {
System.out.println("viewAccepted(): member #" + memNum++ + " = " + member);
}
String myClusterName = channel.getName();
System.out.println("viewAccepted(): my clusterName = \"" + myClusterName + "\"");
if (viewMembers.size() > 0) {
String clusterActive = viewMembers.get(0).toString();
System.out.println("viewAccepted(): " + clusterName + ", cluster active = \"" + clusterActive + "\"\n");
}
}
@Override
public void receive(Message arg0) {
System.out.println("receive called, message = \"" + arg0 + "\"");
}
/**
* @param args
*/
public static void main(String[] args) {
ClusterTest tester = new ClusterTest(args);
tester.joinCluster();
}
}
我通过按 control-C 退出测试应用程序,所以这是一个不优雅的退出。
我们的 Linux 管理员查看了日志,没有发现任何异常。管理员还表示,没有任何限制或配置会抑制 UDP 流量。
我尝试过的事情:
- 根据 this 解决方案增加多播的发送和接收缓冲区大小。由于缓冲区大小不足,我现在在启动时没有收到任何警告消息。
- 正在将 JGroups 版本更新到最新版本。
- 正在等待一夜以尝试启动已停止的主机。
我不想尝试的事情:
- 使用 TCP,因为集群成员是可变的(它可以是任何两个主机),我不想在主机更改时更新配置文件。
如果我无法让 JGroups 可靠地工作,我愿意接受替代解决方案。
谢谢!
看起来您正在使用 JGroups 的默认 (udp.xml) 配置。为什么不复制 udp.xml(例如到您的主目录)并显式设置 UDP.bind_addr
和 UDP.mcast_addr
,然后将 udp.xml 传递给 JChannel 构造函数(new JChannel("/home/user/udp.xml")
)?
例如
<UDP bind_addr="site_local" mcast_addr="232.5.5.5".../>
运行后,您可以使用探针查看实际设置了哪些值:
probe.sh jmx=UDP.bind,mcast
(回答我自己的问题)尽管我说我不想,但我还是继续使用 TCP,但我有点绝望,而且软件交付晚了。我没有看到我在 UDP 上看到的不良行为,其中包括主机无限期地相互忽略的外观。我修改了 vanilla TCP 配置文件以获得所需的性能。
我不打算采用 UDP 解决方案,因为我还有其他工作要做,而且 TCP 解决方案似乎足以投入生产。
我正在使用 JGroups 通过让两台机器加入同名组来创建一个集群,但我的分组行为不稳定,我想问是否有 JGroups 配置更改或我需要更改服务器配置才能使其正常工作。
当我在 JGroups 组中有两个主机时,一个成员离开,另一个成员在 viewAccepted 中观察到这一点。但是当较早的成员 returns 时,他们在 viewAccepted 函数中都看不到对方,并且他们 运行 在有效独立的组中(不好)。这种非分组行为可以是随机的。比如我昨天下午5点断开了一台主机,今天早上重启了一台主机,群里都没看到另一台。然而,一旦我停止他们两个并重新启动,他们在组中找到了对方。
JGroups 的最终用途是将两个 Tomcat 主机 运行 连接到同一个应用程序,这样集群中列出的第一台主机 运行s 报告,而第二台等待第一个死去,然后接替第一个宿主的位置和 运行 的报告。当第一台主机恢复服务时,它成为集群成员列表中的第二台,并等待另一台主机死亡。现在应用程序的行为与下面的测试程序的行为相呼应。
使用开箱即用的 JGroups jgroups-4.1.6.Final.jar,没有自定义 udp.xml 文件,也没有新 JChannel() 的参数。我有一个测试应用程序 运行s 在两个 RHEL 7 主机上让它们集群。代码如下:
import java.util.List;
import org.jgroups.Address;
import org.jgroups.JChannel;
import org.jgroups.Message;
import org.jgroups.Receiver;
import org.jgroups.View;
public class ClusterTest implements Receiver {
private String clusterName;
private JChannel channel;
public ClusterTest(String[] args) {
if (args.length > 0) {
clusterName = args[0];
} else {
clusterName = "TEST_CLUSTER";
}
}
/**
* Joins the JGroups cluster
*/
private void joinCluster() {
System.out.println("joinCluster(): joining cluster \"" + clusterName + "\"");
try {
channel = new JChannel();
channel.setReceiver(this);
channel.connect(clusterName);
} catch (Exception e) {
System.out.print("joinCluster failed: ");
e.printStackTrace();
}
}
@Override
public void viewAccepted(View view) {
System.out.println("viewAccepted(): view = \"" + view + "\" for name = \"" + channel.getName() + "\" / \"" + channel.clusterName() + "\"");
List<Address> viewMembers = view.getMembers();
int memNum = 0;
for (Address member : viewMembers) {
System.out.println("viewAccepted(): member #" + memNum++ + " = " + member);
}
String myClusterName = channel.getName();
System.out.println("viewAccepted(): my clusterName = \"" + myClusterName + "\"");
if (viewMembers.size() > 0) {
String clusterActive = viewMembers.get(0).toString();
System.out.println("viewAccepted(): " + clusterName + ", cluster active = \"" + clusterActive + "\"\n");
}
}
@Override
public void receive(Message arg0) {
System.out.println("receive called, message = \"" + arg0 + "\"");
}
/**
* @param args
*/
public static void main(String[] args) {
ClusterTest tester = new ClusterTest(args);
tester.joinCluster();
}
}
我通过按 control-C 退出测试应用程序,所以这是一个不优雅的退出。
我们的 Linux 管理员查看了日志,没有发现任何异常。管理员还表示,没有任何限制或配置会抑制 UDP 流量。
我尝试过的事情:
- 根据 this 解决方案增加多播的发送和接收缓冲区大小。由于缓冲区大小不足,我现在在启动时没有收到任何警告消息。
- 正在将 JGroups 版本更新到最新版本。
- 正在等待一夜以尝试启动已停止的主机。
我不想尝试的事情:
- 使用 TCP,因为集群成员是可变的(它可以是任何两个主机),我不想在主机更改时更新配置文件。
如果我无法让 JGroups 可靠地工作,我愿意接受替代解决方案。
谢谢!
看起来您正在使用 JGroups 的默认 (udp.xml) 配置。为什么不复制 udp.xml(例如到您的主目录)并显式设置 UDP.bind_addr
和 UDP.mcast_addr
,然后将 udp.xml 传递给 JChannel 构造函数(new JChannel("/home/user/udp.xml")
)?
例如
<UDP bind_addr="site_local" mcast_addr="232.5.5.5".../>
运行后,您可以使用探针查看实际设置了哪些值:
probe.sh jmx=UDP.bind,mcast
(回答我自己的问题)尽管我说我不想,但我还是继续使用 TCP,但我有点绝望,而且软件交付晚了。我没有看到我在 UDP 上看到的不良行为,其中包括主机无限期地相互忽略的外观。我修改了 vanilla TCP 配置文件以获得所需的性能。
我不打算采用 UDP 解决方案,因为我还有其他工作要做,而且 TCP 解决方案似乎足以投入生产。