多播与Hazelcast服务自动发现,如何检测多播是否可用

2022-05-23 00:00:00 分布式 方式 网络 发现 组播

多播(也叫组播)是IP层网络传播的一种方式,我们都听说过还有单播和广播等。但多播的具体应用却很少,不过近在分布式组件Hazelcast的使用中,发现其有3种服务发现的方式,其中一种就是多播,所以来研究下。

Hazelcast简介
Hazelcast是一个分布式计算和存储平台。本质是用Java实现的分布式缓存组件,同时还自带SQL查询,不仅可以像使用Java集合那样操作,还可以通过SQL来查询。看它和Redis的性能比较,还更胜一筹。
总之,这个组件还支持云原生,能做的事情很多,有兴趣可以多了解下。
比如,下面是作为分布式缓存集合的使用,有了它,可以替换掉redis。

下面的代码基于配置文件创建了Hazelcast实例,使用其Map实现key-value存储。

public final static String MAP_NAME = "map-name";

private final HazelcastInstance hi = createInstance();

private HazelcastInstance createInstance() {
System.setProperty("hazelcast.ignoreXxeProtectionFailures", "true");
return Hazelcast.newHazelcastInstance(new ClasspathXmlConfig("hazelcast.xml"));
}

public String setString(String key, String value, int ttlTimeInSec) {
hi.getMap(MAP_NAME).put(key, value, ttlTimeInSec, TimeUnit.SECONDS);
return value;
}

public String setString(String key, String value) {
hi.getMap(MAP_NAME).put(key, value);
return value;
}

public String getString(String key) {
return String.valueOf(hi.getMap(MAP_NAME).get(key));
}

重点就是其分布式能力,这些数据可以在多个节点自动同步。不过,同步的方式基于网络配置。

服务发现
Hazelcast有3种服务发现机制,分别是:

自动发现: AWS等云服务的自动检测与发现
多播
TCP/IP:配置指定的IP来发现
除了多播,其他2种都好使用,自动发现什么都不用配,不过可能不会成功。TCP/IP的方式如下示例:

<hazelcast xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.hazelcast.com/schema/config
http://www.hazelcast.com/schema/config/hazelcast-config-4.6.xsd">

<cluster-name>my-cache</cluster-name>
<management-center scripting-enabled="false"/>
<network>
<join>
<tcp-ip enabled="true">
<members>10.111.11.184-190,10.111.11.177</members> <!--逗号分割多个IP,或后一部分使用-连接连续的IP-->
</tcp-ip>
</join>
</network>
<map name="map-name">
<!--map缓存多30min-->
<time-to-live-seconds>1800</time-to-live-seconds>
</map>
</hazelcast>

重点说一下多播的方式。
实际上,dubbo的multicast注册中心 也是采用的多播形式。
我们看其文档,会提到下面内容:

Multicast 注册中心不需要启动任何中心节点,只要广播地址一样,就可以互相发现。

同时要注意这一句:

组播受网络结构限制,只适合小规模应用或开发阶段使用。组播地址段: 224.0.0.0 - 239.255.255.255

其实,这已经说出了多播所有的要点。
首先,网络是分段的,给多播规定的网络段就是 224.0.0.0 - 239.255.255.255,这里面的IP都可以作为多播地址,因此,看到hazelcast的配置文件里的 multicast-group配置就不会迷茫了。

<network>
<join>
<multicast enabled="true">
<multicast-group>224.2.2.3</multicast-group>
<multicast-port>54327</multicast-port>
<trusted-interfaces>
<interface>10.111.11.*</interface>
</trusted-interfaces>
</multicast>
</join>
</network>

Java中的多播
不过,要理解其原理,我们还是用Java来实现一个小demo,体验本质过程。
我们写一个生产消费者,不过是通过多播来实现。

下面是生产者代码:

private static DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static byte[] buf = new byte[256];

public static void multicastSender(String host, int port) throws IOException {
DatagramSocket socket = new DatagramSocket();
InetAddress group = InetAddress.getByName(host);
String date = FORMATTER.format(LocalDateTime.now());
byte[] buf = date.getBytes(StandardCharsets.UTF_8);
socket.send(new DatagramPacket(buf, buf.length, group, port));
System.out.println("组播写入数据:" + date);
socket.close();
}

下面是消费者代码:

private static void multicastReceiver(String host, int port) throws IOException, InterruptedException {
MulticastSocket socket = new MulticastSocket(port);
InetAddress group = InetAddress.getByName(host);
socket.joinGroup(group);
while (!Thread.interrupted()) {
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String data = new String(packet.getData(), 0, packet.getLength());
System.out.println("组播收到数据:" + data);
if ("quit".equals(data)) {
break;
}
TimeUnit.SECONDS.sleep(1);
}
socket.leaveGroup(group);
socket.close();
}

代码是通过UDP的方式发送消息,传入的参数是域名和端口,比如 224.0.0.200, 5701.
分别起发送者和消费者,应该可以收到消息。
(其他语言也有相应的网络模块可以运行多播).

多播什么时候可用
在本地电脑上,一般可以运行上面的示例,能发送消息,也能收到。
但是,在服务器上的多台机器,不一定可以成功,得看linux主机和网络环境。

确定所处环境是否支持组播,通过如下方式:

1.查看使用的网卡信息: 需要包含MULTICAST

# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.111.11.190 netmask 255.255.252.0 broadcast 10.111.11.255
1
2
3
可以通过ifconfig eth0 multicast启用 或 ifconfig eth0 -multicast禁用eth0网卡的组播。

2.测试组播是否真的可行
选择局域网的2台机器,使用nc来检查。
首先确定组播的group ip,一般为 224.0.0.1

# netstat -gn
IPv6/IPv4 Group Memberships
Interface RefCnt Group
--------------- ------ ---------------------
lo 1 224.0.0.1
eth0 1 224.0.0.1

然后在一台机器上启动一个UDP服务端:

[root@10-117just]# nc -vlu 224.0.0.1 5555
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Listening on 224.0.0.1:5555
1
2
3
另一台机器启动UDP客户端,来发送消息

[root@10-119 tmp2]# nc -vu 224.0.0.1 5555
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Connected to 224.0.0.1:5555.
hello
hehe


然后在客户端输入信息回车发送,如果服务端能收到,说明支持组播。
否则,组播有问题。

总结
虽然多播用的不多,但对于网络的理解必不可少。由点到面,可以扩展出很多知识,这是学习的关联性。
————————————————
版权声明:本文为CSDN博主「悟初境」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jimo_lonely/article/details/120321582

相关文章