多播与Hazelcast服务自动发现,如何检测多播是否可用
多播(也叫组播)是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
相关文章