分布式通信框架 - JGroups

在分布式系统开发中,节点间的通信和协调是一个核心问题。JGroups 作为一个成熟的 Java 集群通信框架,为构建可靠的分布式应用提供了强大的基础设施。

JGroups 是一个用于创建可靠组通信的 Java 工具包。它允许应用程序创建进程组,组内成员可以相互发送消息,并且能够处理节点的加入、离开以及故障恢复等场景。JGroups 被广泛应用于 JBoss、Infinispan、ActiveMQ 等知名开源项目中。

JGroups

核心特性

1、可靠的消息传递:保证消息的有序性和可靠性

2、组成员管理:自动处理节点的加入和离开

3、故障检测:及时发现并处理节点故障

4、灵活的协议栈:支持多种网络协议和传输方式

5、高性能:经过优化的消息传递机制

Protocol Stack(协议栈)

协议栈是 JGroups 的心脏,由多个协议层组成,每个协议层负责特定的功能:

复制代码
传输层协议:UDP、TCP、TUNNEL
故障检测协议:FD、FD_SOCK、VERIFY_SUSPECT
可靠传输协议:UNICAST3、NAKACK2
组成员协议:PING、MERGE3、GMS
流量控制协议:UFC、MFC
排序协议:SEQUENCER、FRAG3

基础使用示例
1. 创建简单的集群应用

java 复制代码
public class Chat {
    public static void main(String[] args) throws Exception {
        // 创建通道--指定协议配置文件
        JChannel channel = new JChannel("jgroups-tcp.xml");
        // 设置接收器
        channel.setReceiver(new Receiver() {
            @Override
            public void receive(Message msg) {
                System.out.println(msg.getObject().toString());
                Receiver.super.receive(msg);
            }
        });
        // 连接到集群
        channel.connect("ChatCluster");

        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            // 发送消息
            String line = in.readLine();
            if ("exit".equals(line)) break;
            Message msg =new ObjectMessage(null, line);
            channel.send(msg);
        }
        channel.close();
    }
}

配置文件jgroups-tcp.xml

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!--
  JGroups TCP配置文件
-->
<config xmlns="urn:org:jgroups"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/jgroups.xsd">
    
    <!-- TCP传输协议 -->
    <TCP bind_port="7800"
         recv_buf_size="5M"
         send_buf_size="5M"
         sock_conn_timeout="300"
         thread_pool.enabled="true"
         thread_pool.min_threads="2"
         thread_pool.max_threads="8"
         port_range="2"
         thread_pool.keep_alive_time="5000"/>

    <!-- TCP节点发现协议 -->
    <TCPPING initial_hosts="localhost[7800],localhost[7801]"
             port_range="1" />
    
    <!-- 合并协议 -->
    <MERGE3 max_interval="30000"
            min_interval="10000"/>

    <!-- 验证协议 -->
    <VERIFY_SUSPECT timeout="1500"/>
    
    <!-- 可靠的单播协议 -->
    <pbcast.NAKACK2 xmit_interval="500"
                    xmit_table_num_rows="100"
                    xmit_table_msgs_per_row="2000"
                    xmit_table_max_compaction_time="30000"
                    use_mcast_xmit="false"
                    discard_delivered_msgs="true"/>
    
    <!-- 单播协议 -->
    <UNICAST3 xmit_interval="500"
              xmit_table_num_rows="100"
              xmit_table_msgs_per_row="1000"
              xmit_table_max_compaction_time="60000"/>
    

    
    <!-- 组成员协议 -->
    <pbcast.GMS print_local_addr="true" join_timeout="2000"/>
    
    <!-- 消息分片协议 -->
    <UFC max_credits="2M"
         min_threshold="0.4"/>
    
    <!-- 消息分片协议 -->
    <MFC max_credits="2M"
         min_threshold="0.4"/>
    
    <!-- 消息压缩协议 -->
    <FRAG2 frag_size="60K"/>
    
    <!-- 状态传输协议 -->
    <pbcast.STATE_TRANSFER/>
    
</config>

注意,并不需要事先显式地创建一个集群,如果是集群第一个实例,Connect()将创建集群。所有连接同一集群的实例将在同一集群中,

2. 编程方式自定义协议栈配置

java 复制代码
public class ProgrammaticChat {

    public static void main(String[] args) throws Exception {
        Protocol[] prot_stack={
                new UDP().setValue("bind_addr", InetAddress.getByName("127.0.0.1")),
                new PING(),
                new MERGE3(),
                new FD_SOCK(),
                new FD_ALL(),
                new VERIFY_SUSPECT(),
                new BARRIER(),
                new NAKACK2(),
                new UNICAST3(),
                new STABLE(),
                new GMS(),
                new UFC(),
                new MFC(),
                new FRAG2()};
        JChannel ch=new JChannel(prot_stack).name("");

        ch.setReceiver(new Receiver() {
            public void viewAccepted(View new_view) {
                System.out.println("view: " + new_view);
            }

            public void receive(Message msg) {
                System.out.println("<< " + msg.getObject() + " [" + msg.getSrc() + "]");
            }
        });

        ch.connect("ChatCluster");
        for(;;) {
            String line= Util.readStringFromStdin(": ");
            ch.send(null, line); // causes an ObjectMessage to be created
        }
    }

}

集群信息交互效果

节点一发送消息

image-20250714102639533

image-20250714102639533

节点二接收消息

总结

JGroups 作为一个成熟的集群通信框架,为构建可靠的分布式应用提供了强大的基础设施。在实际应用中,需要根据具体的业务需求和网络环境选择合适的协议配置,并注意性能优化和故障处理。更多功能参见官方文档http://www.jgroups.org/manual5/index.html#_overview

相关推荐
搞数据的小杰7 小时前
spark广播表大小超过Spark默认的8GB限制
大数据·数据库·分布式·spark
isNotNullX7 小时前
数据怎么分层?从ODS、DW、ADS三大层一一拆解!
大数据·开发语言·数据仓库·分布式·spark
Akamai中国8 小时前
为何说分布式 AI 推理已成为下一代计算方式
人工智能·分布式·云计算·边缘计算·云服务·akamai
Bug退退退12311 小时前
RabbitMQ 之顺序性保障
服务器·分布式·rabbitmq
羌俊恩15 小时前
分布式存储之Ceph使用指南--部署篇(未完待续)
分布式·ceph·pg·osd·rados
wb18915 小时前
LVS的集群技术和分布式
运维·笔记·分布式·云计算·lvs
汀、人工智能15 小时前
AI-Compass LLM训练框架生态:整合ms-swift、Unsloth、Megatron-LM等核心框架,涵盖全参数/PEFT训练与分布式优化
人工智能·分布式·sft·swift·大模型训练
武子康19 小时前
Java-71 深入浅出 RPC Dubbo 上手 父工程配置编写 附详细POM与代码
java·分布式·程序人生·spring·微服务·rpc·dubbo