ActiveMQ静态网络配置

1,环境准备

    * 三台Linux服务器(虚拟机即可)

    * ActiveMQ安装包

    * 关闭服务器,解压安装包文件到服务器;依次启动,查看服务是否正常;一切就绪后进行文件配置

activemq 配置 topic queue 两种工厂 activemq集群配置_ActiveMQ

2,配置文件

    * 在activemq.xml中修改broker名称

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="cluster_1" dataDirectory="${activemq.data}">

    * 在activemq.xml文件中配置静态网络的集群节点

    * 三台服务器中全部配置,保证三台服务器间可以正常互通

<networkConnectors>
       <networkConnector uri="static://(tcp://192.168.91.128:61616,tcp://192.168.91.129:61616,tcp://192.168.91.130:61616)"/>
</networkConnectors>

    * 三台启动完成后,页面效果

activemq 配置 topic queue 两种工厂 activemq集群配置_静态网络配置_02

3,静态网络互通测试

    * 服务端发送消息到128节点

public class ActiveMQProducer {
    public static void main(String[] args) throws JMSException {
        // 获取链接工厂
        ConnectionFactory connectionFactory =
                new ActiveMQConnectionFactory("tcp://192.168.91.128:61616");
        // 创建链接
        Connection connection = connectionFactory.createConnection();
        connection.start();
        // 创建会话
        Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
        // 创建目的地
        Destination destination = session.createQueue("myQueue");
        // 创建生产者
        MessageProducer producer = session.createProducer(destination);
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);
        // 创建消息
        for (int i = 1; i <= 10; i++) {
            TextMessage message = session.createTextMessage("producer send message : " + i);
            // 生产者发送消息
            producer.send(message);
        }
        session.commit();
        session.close();
        System.out.println("消息发送成功");
    }
}

activemq 配置 topic queue 两种工厂 activemq集群配置_集群_03

    * 消费端1从129节点消费消息

public class ActiveMQConsumer {
    public static void main(String[] args) throws JMSException, InterruptedException {
        ConnectionFactory connectionFactory = 
                new ActiveMQConnectionFactory("tcp://192.168.91.129:61616?" +
                        "jms.optimizeAcknowledge=true&" +
                        "jms.optimizeAcknowledgeTimeOut=10000");
        // 创建链接
        Connection connection = connectionFactory.createConnection();
        connection.start();
        // 创建会话
        Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
        // 创建目的地
        Destination destination = session.createQueue("myQueue?consumer.prefetchSize=10");
        // 创建消费者
        MessageConsumer consumer = session.createConsumer(destination);
        for (int i = 0; i < 10; i++) {
            // 接收信息
            TextMessage textMessage = (TextMessage) consumer.receive();
            // 消费信息
            System.out.println("消费者1 : " + textMessage.getText());
            session.commit();
        }

    }
}

activemq 配置 topic queue 两种工厂 activemq集群配置_hakadb_04

         * 128节点显示129节点消费

activemq 配置 topic queue 两种工厂 activemq集群配置_ActiveMQ_05

         * 129节点消费记录

activemq 配置 topic queue 两种工厂 activemq集群配置_静态网络配置_06

    * 消费端2从130节点消费消息

public class ActiveMQConsumer1 {
    public static void main(String[] args) throws JMSException, InterruptedException {
        ConnectionFactory connectionFactory =
                new ActiveMQConnectionFactory("tcp://192.168.91.130:61616?" +
                        "jms.optimizeAcknowledge=true&" +
                        "jms.optimizeAcknowledgeTimeOut=10000");
        // 创建链接
        Connection connection = connectionFactory.createConnection();
        connection.start();
        // 创建会话
        Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
        // 创建目的地
        Destination destination = session.createQueue("myQueue?consumer.prefetchSize=10");
        // 创建消费者
        MessageConsumer consumer = session.createConsumer(destination);
        while (true) {
            // 接收信息
            TextMessage textMessage = (TextMessage) consumer.receive();
            // 消费信息
            System.out.println("消费者2 : " + textMessage.getText());
            session.commit();
        }

    }
}

activemq 配置 topic queue 两种工厂 activemq集群配置_LevelDB_07

        * 128节点显示130节点消费

activemq 配置 topic queue 两种工厂 activemq集群配置_集群_08

        * 130节点消费记录

activemq 配置 topic queue 两种工厂 activemq集群配置_集群_09

4,消息回流

    * 静态网络配置好后,如果节点服务全部正常,则整个发布消费流程不会存在问题;但是如果在服务发布消费过程中,存在节点宕机,这就会存在消息丢失的风险,配置消息回流能够有效的防止消息丢失;

    * 配置方式 -- 在activemq.xml标签<policyEntries>中添加配置信息

<policyEntry queue=">" enableAudit="false"> 
	<networkBridgeFilterFactory> 
		<conditionalNetworkBridgeFilterFactory replayWhenNoConsumers="true"/> 
	</networkBridgeFilterFactory> 
</policyEntry>

    * 配置完成后重启服务使其生效

5,消息回流测试

    * 服务端发送消息到128节点

activemq 配置 topic queue 两种工厂 activemq集群配置_集群_10

    * 消费端消费部分消息后模拟宕机,重启activemq服务

activemq 配置 topic queue 两种工厂 activemq集群配置_hakadb_11

activemq 配置 topic queue 两种工厂 activemq集群配置_LevelDB_12

    * 重启完成后,重新执行消费端进行消费,可以发现消费端继续进行消费,有部分重复是因为多次执行

activemq 配置 topic queue 两种工厂 activemq集群配置_集群_13

基于LevelDB+Zookeeper构建ActiveMQ集群

1,环境准备

    * 三台Linux服务器

    * ActiveMQ安装包

    * Zookeeper集群

2,配置文件 -- activemq.xml

    * 修改brokerName,三台机器brokerName统一修改为“activemq_cluster”

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="activemq_cluster" dataDirectory="${activemq.data}">

    * 修改存储方式(默认为kahadb),修改为levelDB+ZK集群方式,hostName为当前节点IP

<persistenceAdapter>
  <!--  <kahaDB directory="${activemq.data}/kahadb"/> -->
		<replicatedLevelDB
				directory="${activemq.data}/leveldb"
				replicas="3"
				bind="tcp://0.0.0.0:62621"
				zkAddress="192.168.91.128:2181,192.168.91.129:2181,192.168.91.130:2181"
				hostname="192.168.91.130"
				zkPath="/activemq/leveldb-stores" />
</persistenceAdapter>

    * 集群启动:启动后只有当前主节点可以进行访问,且zookeeper节点上注册三个activemq服务节点

activemq 配置 topic queue 两种工厂 activemq集群配置_集群_14

activemq 配置 topic queue 两种工厂 activemq集群配置_ActiveMQ_15

3,服务端发布消息

public class ActiveMQClusterProducer {
    public static void main(String[] args) throws JMSException {
        // 获取链接工厂
        ConnectionFactory connectionFactory =
                new ActiveMQConnectionFactory(
                        "failover:(" +
                        "tcp://192.168.91.128:61616," +
                        "tcp://192.168.91.129:61616," +
                        "tcp://192.168.91.130:61616)?randomize=false");
        // 创建链接
        Connection connection = connectionFactory.createConnection();
        connection.start();
        // 创建会话
        Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
        // 创建目的地
        Destination destination = session.createQueue("myQueue");
        // 创建生产者
        MessageProducer producer = session.createProducer(destination);
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);
        // 创建消息
        for (int i = 1; i <= 10; i++) {
            TextMessage message = session.createTextMessage("producer send message : " + i);
            // 生产者发送消息
            producer.send(message);
        }
        session.commit();
        session.close();
        System.out.println("消息发送成功");
    }
}

activemq 配置 topic queue 两种工厂 activemq集群配置_静态网络配置_16

4,客户端消费消息

public class ActiveMQConsumer {
    public static void main(String[] args) throws JMSException, InterruptedException {
        ConnectionFactory connectionFactory =
                new ActiveMQConnectionFactory(
                        "failover:(" +
                                "tcp://192.168.91.128:61616," +
                                "tcp://192.168.91.129:61616," +
                                "tcp://192.168.91.130:61616)?randomize=false");
        // 创建链接
        Connection connection = connectionFactory.createConnection();
        connection.start();
        // 创建会话
        Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
        // 创建目的地
        Destination destination = session.createQueue("myQueue?consumer.prefetchSize=10");
        // 创建消费者
        MessageConsumer consumer = session.createConsumer(destination);
        for (int i = 0; i < 100; i++) {
            // 接收信息
            TextMessage textMessage = (TextMessage) consumer.receive();
            // 消费信息
            System.out.println("消费者1 : " + textMessage.getText());
            session.commit();
        }

    }
}

activemq 配置 topic queue 两种工厂 activemq集群配置_静态网络配置_17

5,参数解析

    * randomize=true 客户端会随机对三个节点进行连接,当第一个节点宕机了,会依次链接其他节点

    * randomize=false , 所有的客户端连接都会打在第一个ip:port 上,只有第一个挂了,他才会打在第二个mq 上

基于kahadb构建ActiveMQ集群

1,环境准备

    * 三台Linux服务器

    * ActiveMQ安装包

 2,构建挂载在三台服务器下的共享文件夹

    * 安装NFS服务

            # yum install nfs-utils

    * 服务端创建共享文件夹,修改/etc/exports文件

            # /home/work 192.168.91.*(insecure,rw,sync,no_root_squash)

    * 启动NFS和rpcbind

           # service rpcbind start

           # service nfs start

    * 服务端检查服务器的NFS状态

           # showmount -e

    * 客户端查询服务端共享目录

           # showmount -e 192.168.91.128

    * 创建客户端共享目录

           # cd /mnt

           # mkdir static

    * 挂载服务端的共享目录

           # mount -t nfs -o nolock,nfsvers=3,vers=3 192.168.91.128:/home/work /mnt/static

    * 挂载在服务器下的共享文件夹为 /mnt/static

3,集群搭建

    * 配置broker信息,brokerName三个节点不能一样,dataDirectory为上一步配置的共享文件夹

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="activemq-cluster_1" dataDirectory="/mnt/static">

    * 加载配置信息

<persistenceAdapter>
    <kahaDB directory="/mnt/static/kahadb"
			journalMaxFileLength="32mb"
			enableJournalDiskSyncs="true"
			enableIndexWriteAsync="true"
			indexCacheSize="1000"
			indexWriteBatchSize="1000"/>
</persistenceAdapter>

<networkConnectors>
    <networkConnector uri="masterslave:(tcp://192.168.91.128:61616,tcp://192.168.91.129:61616,tcp://192.168.91.130:61616)"
                      duplex="true"
					  dynamicOnly="true"
					  networkTTL="3"
					  prefetchSize="1"
					  decreaseNetworkConsumerPriority="true"
					  conduitSubscriptions="false"/>
</networkConnectors>

    * 启动后集群状态

activemq 配置 topic queue 两种工厂 activemq集群配置_ActiveMQ_18

4,集群测试

    -- 部分配置存在问题,正在处理中