• ActiveMQ集群搭建


      集群方案主要为了解决系统架构中的两个关键问题:高可用高性能。ActiveMQ服务的高可用性是指,在ActiveMQ服务性能不变、数据不丢失的前提下,确保当系统灾难出现时ActiveMQ能够持续提供消息服务,高可靠性方案最终目的是减少整个ActiveMQ停止服务的时间。

      ActiveMQ服务的高性能是指,在保证ActiveMQ服务持续稳定性、数据不丢失的前提下,确保ActiveMQ集群能够在单位时间内吞吐更高数量的消息、确保ActiveMQ集群处理单条消息的时间更短、确保ActiveMQ集群能够容纳更多的客户端稳定连接。

      下面我们分别介绍如何通过多个ActiveMQ服务节点集群方式,分别提供热备方案和高性能方案。最后我们讨论如何将两种方案结合在一起,最终形成在生成环境下使用的推荐方案。

    一、高可用集群

    以下内容来自:

    ActiveMQ+ZooKeeper 伪集群整合https://segmentfault.com/a/1190000014636822

    ActiveMQ+ZooKeeper 集群整合https://segmentfault.com/a/1190000014635114

    1.1、ActiveMQ+ZooKeeper 伪集群整合

    伪集群方式,即在一台主机上部署3个activemq服务(端口不同)+3个zookeeper服务(端口不同)

    原理简介:
    一般在部署ActiveMQ集群的时候,更倾向于使用基于ZooKeeper的Replicated LevelDB Store方式,该方式是Master Slave部署方案的其中一种策略,也是在多台主机实现ActiveMQ集群的主流部署方式。 这里只保证了高可用性。要想保证负载均衡得再结合Broker Clusters 部署方案,配置网络连接器。

    工作流程:
    在ZooKeeper中管理多个Broker节点,根据 Master选举策略让其中一个 Broker选举为Master(只有Master才具备对外提供服务的能力),剩下Broker为slave。
    编码时,client端(消费者)通过failover协议来连接ActiveMQ集群。

    1.1.1、ZooKeeper伪集群配置

    规划

    --服务端口集群通信端口节点目录/usr/local下
    zk1 2181 2881:3881 /zookeeper/zk1
    zk2 2182 2882:3882 /zookeeper/zk2
    zk3 2183 2883:3883 /zookeeper/zk3

    集群通信端口:第一个端口是master和slave之间的通信端口,默认是2881;第二个端口是leader选举的端口,集群刚启动的时候选举或者leader挂掉之后进行新的选举的端口默认是3881。

    配置zoo.cfg文件,创建myid

    zk1/conf/zoo.cfg:

    # zookeeper的数据存储和日志存储目录(如果目录不存在就新建)
    dataDir=/usr/local/zookeeper/zk1/data
    dataLogDir=/usr/local/zookeeper/zk1/log
    
    #服务端口
    clientPort=2181
    
    # zk集群之间的通信地址
    server.1=localhost:2881:3881
    server.2=localhost:2882:3882
    server.3=localhost:2883:3883

    创建zk1/data/myid文件,填入数字1:

    # 由于该zk1是server.1,所以在myid中设置数字1
    $ vim /usr/local/zookeeper/zk1/data/myid

    zk2/conf/zoo.cfg:

    # zookeeper的数据存储和日志存储目录(如果目录不存在就新建)
    dataDir=/usr/local/zookeeper/zk1/data
    dataLogDir=/usr/local/zookeeper/zk1/log
    
    #服务端口
    clientPort=2182
    
    # zk集群之间的通信地址
    server.1=localhost:2881:3881
    server.2=localhost:2882:3882
    server.3=localhost:2883:3883

    创建zk2/data/myid文件,填入数字2:

    # 由于该zk1是server.2,所以在myid中设置数字2
    $ vim /usr/local/zookeeper/zk1/data/myid

    zk3/conf/zoo.cfg:

    # zookeeper的数据存储和日志存储目录(如果目录不存在就新建)
    dataDir=/usr/local/zookeeper/zk1/data
    dataLogDir=/usr/local/zookeeper/zk1/log
    
    #服务端口
    clientPort=2183
    
    # zk集群之间的通信地址
    server.1=localhost:2881:3881
    server.2=localhost:2882:3882
    server.3=localhost:2883:3883

    创建zk3/data/myid文件,填入数字3:

    # 由于该zk1是server.3,所以在myid中设置数字3
    $ vim /usr/local/zookeeper/zk1/data/myid

     

    启动Zookeeper

    $ /usr/local//zookeeper/zk1/bin/zkServer.sh start # 启动zk1服务
    $ /usr/local//zookeeper/zk2/bin/zkServer.sh start # 启动zk2服务
    $ /usr/local//zookeeper/zk3/bin/zkServer.sh start # 启动zk3服务
    
    $ /usr/local//zookeeper/zk1/bin/zkServer.sh status # 查看zk1服务状态
    $ /usr/local//zookeeper/zk2/bin/zkServer.sh status # 查看zk2服务状态
    $ /usr/local//zookeeper/zk3/bin/zkServer.sh status # 查看zk3服务状态

     

    1.1.2、ActiveMQ伪集群配置

    规划

     

    --服务端口jetty控制台端口节点目录/usr/local/下
    node1 61616 8161 /activemq/node1
    node2 61617 8162 /activemq/node2
    node3 61618 8163 /activemq/node3

    对3个activemq服务,并分别配置它们的文件conf/activemq.xml和conf/jetty.xml:

    conf/jetty.xml:

    • node1:

    /usr/local//activemq/node1/conf/activemq.xml:

    <!-- activemq支持5种协议:openwire、amqp、 stomp、mqtt、ws,这里我们只使用openwire协议,注释其它协议 -->
    <transportConnectors>
        <!-- node1服务端口使用默认端口61616 -->
        <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
        <!--
        <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
        -->
    </transportConnectors>
    
    <!-- 持久化的部分为ZooKeeper集群连接地址-->  
    <persistenceAdapter>  
        <replicatedLevelDB  
          directory="${activemq.data}/leveldb"  
          replicas="3"  
          bind="tcp://0.0.0.0:0"  
          zkAddress="localhost:2181,localhost:2182,localhost:2183"   
          zkPath="/usr/local//activemq/leveldb-stores"  
          hostname="localhost"  
          />  
    </persistenceAdapter>
    <!-- 
    # directory: 存储数据的路径
    # replicas:集群中的节点数【(replicas/2)+1公式表示集群中至少要正常运行的服务数量】,3台集群那么允许1台宕机, 另外两台要正常运行  
    # bind:当该节点成为master后,它将绑定已配置的地址和端口来为复制协议提供服务。还支持使用动态端口。只需使用tcp://0.0.0.0:0进行配置即可,默认端口为61616。 
    # zkAddress:ZK的ip和port, 如果是集群,则用逗号隔开(这里作为简单示例ZooKeeper配置为单点, 这样已经适用于大多数环境了, 集群也就多几个配置) 
    # zkPassword:当连接到ZooKeeper服务器时用的密码,没有密码则不配置。 
    # zkPah:ZK选举信息交换的存贮路径,启动服务后actimvemq会到zookeeper上注册生成此路径   
    # hostname: ActiveMQ所在主机的IP
    # 更多参考:http://activemq.apache.org/replicated-leveldb-store.html
    -->

    /usr/local//activemq/conf/jetty.xml:

    <bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
        <property name="host" value="0.0.0.0"/>
        <property name="port" value="8161"/> <!-- 在这里修改端口为8161,默认就是8161 -->
    </bean>
    • node2

    /usr/local//activemq/node2/conf/activemq.xml:

    <transportConnectors>
        <!-- 服务端口改为61617 -->
        <transportConnector name="openwire" uri="tcp://0.0.0.0:61617?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    </transportConnectors>
    
    <!-- 持久化的部分为ZooKeeper集群连接地址-->  
    <persistenceAdapter>  
        <replicatedLevelDB  
          directory="${activemq.data}/leveldb"  
          replicas="3"  
          bind="tcp://0.0.0.0:0"  
          zkAddress="localhost:2181,localhost:2182,localhost:2183"   
          zkPath="/usr/local//activemq/leveldb-stores"  
          hostname="localhost"  
          />  
    </persistenceAdapter>

    /usr/local//activemq/conf/jetty.xml:

    <bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
        <property name="host" value="0.0.0.0"/>
        <property name="port" value="8162"/> <!-- 在这里修改端口为8162,默认是8161 -->
    </bean>
    • node3

    /usr/local//activemq/node3/conf/activemq.xml:

    <transportConnectors>
        <!-- 服务端口改为61618 -->
        <transportConnector name="openwire" uri="tcp://0.0.0.0:61618?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    </transportConnectors>
    
    <!-- 持久化的部分为ZooKeeper集群连接地址-->  
    <persistenceAdapter>  
        <replicatedLevelDB  
          directory="${activemq.data}/leveldb"  
          replicas="3"  
          bind="tcp://0.0.0.0:0"  
          zkAddress="localhost:2181,localhost:2182,localhost:2183"   
          zkPath="/usr/local//activemq/leveldb-stores"  
          hostname="localhost"  
          />  
    </persistenceAdapter>

    /usr/local//activemq/node3/conf/jetty.xml:

    <bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
        <property name="host" value="0.0.0.0"/>
        <property name="port" value="8163"/> <!-- 在这里修改端口为8163,默认是8161 -->
    </bean>

    依次启动activemq服务

    $ /usr/local//activemq/node1/bin/activemq start # 启动节点node1服务
    $ /usr/local//activemq/node2/bin/activemq start # 启动节点node2服务
    $ /usr/local//activemq/node3/bin/activemq start # 启动节点node3服务
    
    $ ps -ef|grep activemq # 检查进程是否运行,即activemq是否启动成功
    $ netstat -anp|grep 61616 # 查看服务端口61616,监听情况
    $ netstat -anp|grep 61617 # 查看服务端口61617,监听情况
    $ netstat -anp|grep 61618 # 查看服务端口61618,监听情况

    1.1.3、Client使用

    该zookeeper+activemq的集群Master Slave部署方案,能够提供(3-1)/2的容错率,即3台服务器允许宕机一台,而不影响整个集群的对外提供服务。

    编写代码连接时使用failover策略:

    String url = failover:(tcp://192.168.8.201:61616,tcp://192.168.8.201:61617,tcp://192.168.8.201:61618)?initialReconnectDelay=1000

    1.2、ActiveMQ+ZooKeeper 集群整合

    使用的是真集群方式,准备三台主机,IP分别为192.168.8.201、192.168.8.202、192.168.8.203

    原理简介:
    一般在部署ActiveMQ集群的时候,更倾向于使用基于ZooKeeper的Replicated LevelDB Store方式,该方式是Master Slave部署方案的其中一种策略,也是在多台主机实现ActiveMQ集群的主流部署方式。 此教程只保证了高可用性。要想保证负载均衡得再结合Broker Clusters 部署方案,配置网络连接器。

    工作流程:
    在ZooKeeper中管理多个Broker节点,根据 Master选举策略让其中一个 Broker选举为Master(只有Master才具备对外提供服务的能力),剩下Broker为slave。
    编码时,client端(消费者)通过failover协议来连接ActiveMQ集群。

    1.2.1、zookeeper集群

    ZooKeeper集群保证ZooKeeper本身的高可用性。

    规划

    主机IP服务端口(默认)集群通信端口节点目录/usr/local/下 
    192.168.8.201 2181 2881:3881 zookeeper
    192.168.8.202 2181 2881:3881 zookeeper
    192.168.8.203 2181 2881:3881 zookeeper

    集群通信端口:第一个端口是master和slave之间的通信端口,默认是2881;第二个端口是leader选举的端口,集群刚启动的时候选举或者leader挂掉之后进行新的选举的端口默认是3881。

    在3台主机上都安装zookeeper服务,/usr/local//zookeeper,并分别配置它们的文件conf/zoo.cfg:

    • 主机1(192.168.8.201)

    /usr/local//zookeeper/conf/zoo.cfg:

    # zookeeper的数据存储和日志存储目录(如果目录不存在就新建)
    dataDir=/usr/local//zookeeper/data
    dataLogDir=/usr/local//zookeeper/log
    
    # zk集群之间的通信地址
    server.1=192.168.8.201:2888:3888
    server.2=192.168.8.202:2888:3888
    server.3=192.168.8.203:2888:3888

    创建/usr/local//zookeeper/data/myid文件,填入数字1:

    # 由于该主机1(192.168.8.201)是server.1,所以在myid中设置数字1
    $ vim /usr/local//zookeeper/data/myid
    • 主机2(192.168.8.202)

      /usr/local//zookeeper/conf/zoo.cfg:
      
      dataDir=/usr/local//zookeeper/data
      dataLogDir=/usr/local//zookeeper/log
      
      server.1=192.168.8.201:2881:3881
      server.2=192.168.8.202:2881:3881
      server.3=192.168.8.203:2881:3881

      创建/usr/local//zookeeper/data/myid文件,填入数字2:

      # 由于该主机2(192.168.8.202)是server.2,所以在myid中设置数字2
      $ vim /usr/local//zookeeper/data/myid
    • 主机3(192.168.8.202)

      /usr/local//zookeeper/conf/zoo.cfg:
      
      dataDir=/usr/local//zookeeper/data
      dataLogDir=/usr/local//zookeeper/log
      
      server.1=192.168.8.201:2881:3881
      server.2=192.168.8.202:2881:3881
      server.3=192.168.8.203:2881:3881

      创建/usr/local//zookeeper/data/myid文件,填入数字3:

      # 由于该主机3(192.168.8.203)是server.3,所以在myid中设置数字3
      $ vim /usr/local//zookeeper/data/myid

    分别启动zookeeper服务

     
    $ /usr/local//zookeeper/bin/zkServer.sh start # 启动zk服务
    $ /usr/local//zookeeper/bin/zkServer.sh status # 查看zk服务状态

     1.2.2、ActiveMQ集群

    规划

    主机IP服务端口(默认)复制协议端口(动态)jetty控制台端口(默认)节点目录/usr/local/下 
    192.168.8.201 61616 tcp://0.0.0.0:0 8161 activemq/node1
    192.168.8.202 61616 tcp://0.0.0.0:0 8161 activemq/node2
    192.168.8.203 61616 tcp://0.0.0.0:0 8161 activemq/node3

    
    

    修改ActiveMQ配置文件conf/activemq.xmlconf/jetty.xml

    在3台主机上都安装activemq 服务,/usr/local//activemq,并分别配置它们的文件conf/activemq.xml和conf/jetty.xml:

    • 主机1(192.168.8.201)

    /usr/local//activemq/conf/activemq.xml:

    <!-- 持久化的部分为ZooKeeper集群连接地址-->  
    <persistenceAdapter>  
        <replicatedLevelDB  
          directory="${activemq.data}/leveldb"  
          replicas="3"  
          bind="tcp://0.0.0.0:0"  
          zkAddress="192.168.8.201:2181,192.168.8.202:2181,192.168.8.203:2181"   
          zkPath="/usr/local//activemq/leveldb-stores"  
          hostname="192.168.8.201"  
          />  
    </persistenceAdapter>
    <!-- 
    # directory: 存储数据的路径
    # replicas:集群中的节点数【(replicas/2)+1公式表示集群中至少要正常运行的服务数量】,3台集群那么允许1台宕机, 另外两台要正常运行  
    # bind:当该节点成为master后,它将绑定已配置的地址和端口来为复制协议提供服务。还支持使用动态端口。只需使用tcp://0.0.0.0:0进行配置即可,默认端口为61616。 
    # zkAddress:ZK的ip和port, 如果是集群,则用逗号隔开(这里作为简单示例ZooKeeper配置为单点, 这样已经适用于大多数环境了, 集群也就多几个配置) 
    # zkPassword:当连接到ZooKeeper服务器时用的密码,没有密码则不配置。 
    # zkPah:ZK选举信息交换的存贮路径,启动服务后actimvemq会到zookeeper上注册生成此路径   
    # hostname: ActiveMQ所在主机的IP
    # 更多参考:http://activemq.apache.org/replicated-leveldb-store.html
    -->

    /usr/local//activemq/conf/jetty.xml:

    <bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
        <property name="host" value="0.0.0.0"/>
        <property name="port" value="8161"/> <!-- 在这里修改端口为8161,默认就是8161 -->
    </bean>
    • 主机2(192.168.8.202)

      /usr/local//activemq/conf/activemq.xml:
      
      <persistenceAdapter>  
          <replicatedLevelDB  
            directory="${activemq.data}/leveldb"  
            replicas="3"  
            bind="tcp://0.0.0.0:0"  
            zkAddress="192.168.8.201:2181,192.168.8.202:2181,192.168.8.203:2181"   
            zkPath="/usr/local//activemq/leveldb-stores"  
            hostname="192.168.8.202"  
            />  
      </persistenceAdapter>

      /usr/local//activemq/conf/jetty.xml:

    <bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
        <property name="host" value="0.0.0.0"/>
        <property name="port" value="8161"/> <!-- 在这里修改端口为8161,默认就是8161 -->
    </bean>
    • 主机3(192.168.8.203)
    /usr/local//activemq/conf/activemq.xml:
    
    <persistenceAdapter>  
        <replicatedLevelDB  
          directory="${activemq.data}/leveldb"  
          replicas="3"  
          bind="tcp://0.0.0.0:0"  
          zkAddress="192.168.8.201:2181,192.168.8.202:2181,192.168.8.203:2181"   
          zkPath="/usr/local//activemq/leveldb-stores"  
          hostname="192.168.8.203"  
          />  
    </persistenceAdapter>

    /usr/local//activemq/conf/jetty.xml:

    <bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
        <property name="host" value="0.0.0.0"/>
        <property name="port" value="8161"/> <!-- 在这里修改端口为8161,默认就是8161 -->
    </bean>

    依次启动activemq服务

    $ /usr/local//activemq/bin/activemq start # 启动activemq服务
    
    $ ps -ef|grep activemq # 检查进程是否运行,即activemq是否启动成功
    $ netstat -anp|grep 61616 # 查看服务端口61616,监听情况

    1.2.3、Client使用

    该zookeeper+activemq的集群Master Slave部署方案,能够提供(3-1)/2的容错率,即3台服务器允许宕机一台,而不影响整个集群的对外提供服务。

    编写代码连接时使用failover策略:

     

    String url = failover:(tcp://192.168.8.201:61616,tcp://192.168.8.202:61616,tcp://192.168.8.203:61616)?initialReconnectDelay=1000

    二、负载均衡集群

    以下内容来自:https://blog.csdn.net/yinwenjie/article/details/51124749

      ActiveMQ的多节点集群方案,主要有动态集群静态集群两种方案。

    • 动态集群:是指同时提供消息服务的ActiveMQ节点数量、位置(IP和端口)是不确定的,当某一个节点启动后,会通过网络组播的方式向其他节点发送通知(同时接受其他节点的组播信息)。当网络中其他节点收到组播通知后,就会向这个节点发起连接,最终将新的节点加入ActiveMQ集群;

    • 静态集群:是指同时提供消息服务的多个节点的位置(IP和端口)是确定的,每个节点不需要通过广播的方式发现目标节点,只需要在启动时按照给定的位置进行连接。

    • 静态集群方案 

    •  动态集群方案

      

    2.1、桥接Network Bridges

       为了实现ActiveMQ集群的横向扩展要求和高稳定性要求,ActiveMQ集群提供了Network Bridges功能。通过Network Bridges功能,技术人员可以将多个ActiveMQ服务节点连接起来。并让它们通过配置好的策略作为一个整体对外提供服务。

    这样的服务策略主要包括两种:主/从模式负载均衡模式。对于第一种策略请看博文ActiveMQ笔记(3):基于Networks of Brokers的HA方案(http://www.cnblogs.com/leihenqianshang/articles/5623841.html)。这里我们要重点讨论的是基于Network Bridges的负载均衡模式。

     

    2.2、动态Network Connectors

       已经清楚了ActiveMQ中的动态节点发现原理和ActiveMQ Network Bridges的概念,那么关于ActiveMQ怎样配置集群的方式就是非常简单的问题了。我们先来讨论如何进行基于组播发现的ActiveMQ负载均衡模式的配置——动态网络连接Network Connectors;再来讨论基于固定地址的负载均衡模式配置——静态网络连接Network Connectors

    要配置基于组播发现的ActiveMQ负载均衡模式,其过程非常简单。开发人员只需要在每一个ActiveMQ服务节点的主配置文件中(activemq.xml),添加/更改 以下配置信息即可:

    ......
    <transportConnectors>
        <!-- 在transportConnector中增加discoveryUri属性,表示这个transportConnector是要通过组播告知其它节点的:使用这个transportConnector位置连接我 -->
        <transportConnector name="auto" uri="auto+nio://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600&amp;org.apache.activemq.transport.nio.SelectorManager.corePoolSize=20&amp;org.apache.activemq.transport.nio.SelectorManager.maximumPoolSize=50&amp;consumer.prefetchSize=5" discoveryUri="multicast://239.0.0.5" />
    </transportConnectors>
    
    ......
    
    <!-- 关键的networkConnector标签, uri属性标示为组播发现-->
    <networkConnectors>
        <networkConnector uri="multicast://239.0.0.5" duplex="false"/>
    </networkConnectors>
    
    ......

    2.2.1、 networkConnector标签

    如果使用ActiveMQ的组播发现功能,请在networkConnector标签的uri属性中添加如下格式的信息:

    multicast://[组播地址][:端口]

    例如,您可以按照如下方式使用ActiveMQ默认的组播地址来发现网络种其他ActiveMQ服务节点:

    #ActiveMQ集群默认的组播地址(239.255.2.3):
    multicast://default

    也可以按照如下方式,指定一个组播地址——这在高安全级别的网络中很有用,因为可能其他的组播地址已经被管理员禁用。注意组播地址只能是D类IP地址段:

    #使用组播地址239.0.0.5
    multicast://239.0.0.5

     以下是通过抓包软件获得的的组播UDP报文

     

    从上图中我们可以获得几个关键信息:

    • 192.168.61.138和192.168.61.139这两个IP地址分别按照一定的周期(1秒一次),向组播地址239.0.0.5发送UDP数据报。以便让在这个组播地址的其它服务节点能够感知自己的存在

    • 另外,以上UDP数据报文使用的端口是6155。您也可以更改这个端口信息通过类似如下的方式:

    #使用组播地址239.0.0.5:19999
    multicast://239.0.0.5:19999
    •  每个UDP数据报中,包含的主要信息包括本节点ActiveMQ的版本信息,以及连接到自己所需要使用的host名字、协议名和端口信息。类似如下:
    default.ActiveMQ-4.ailve%localhost%auto+nio://activemq:61616

     2.2.2、transportConnector标签的关联设置

    任何一个ActiveMQ服务节点A,要连接到另外的ActiveMQ服务节点,都需要使用当前节点A已经公布的transportConnector连接端口,例如以下配置中,能够供其它服务节点进行连接的就只有两个transportConnector连接中的任意一个:

    ......
    <transportConnectors>
        <!-- 其它ActiveMQ服务节点,只能使用以下三个连接协议和端口进行连接 -->
        <!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
        <transportConnector name="tcp" uri="tcp://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="nio" uri="nio://0.0.0.0:61618?maximumConnections=1000" />
        <transportConnector name="auto" uri="auto://0.0.0.0:61617?maximumConnections=1000" />   
    </transportConnectors>
    ......

     那么要将哪一个连接方式通过UDP数据报向其他ActiveMQ节点进行公布,就需要在transportConnector标签上使用discoveryUri属性进行标识,如下所示:

    ......
    <transportConnectors>
        ......
        <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
        <transportConnector name="auto" uri="auto+nio://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600" discoveryUri="multicast://239.0.0.5" />
    </transportConnectors>
    
    ......
    <networkConnectors>
        <networkConnector uri="multicast://239.0.0.5"/>
    </networkConnectors>
    ......

    2.3、静态Network Connectors

    相比于基于组播发现方式的动态Network Connectors而言,虽然静态Network Connectors没有那样灵活的横向扩展性,但是却可以适用于网络环境受严格管理的情况。例如:管理员关闭了交换机/路由器的组播功能、端口受到严格管控等等。

    配置静态Network Connectors的ActiveMQ集群的方式也很简单,只需要更改networkConnectors标签中的配置即可,而无需关联改动transportConnectors标签。但是配置静态Network Connectors的ActiveMQ集群时,需要注意非常关键的细节:每一个节点都要配置其他所有节点的连接位置。

    为了演示配置过程,我们假设ActiveMQ集群由两个节点构成,分别是activemq1:192.168.61.138 和 activemq2:192.168.61.139。那么配置情况如下所示:

    • 192.168.61.138:需要配置activemq2的位置信息以便进行连接:
    ......
    <transportConnectors>
        <transportConnector name="auto" uri="auto+nio://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600&amp;consumer.prefetchSize=5"/>
    </transportConnectors>
    ......
    
    <!-- 请注意,一定需要192.168.61.139(activemq2)提供了这样的连接协议和端口 -->
    <networkConnectors>
        <networkConnector uri="static:(auto+nio://192.168.61.139:61616)"/>
    </networkConnectors>
    ......
    • 192.168.61.139:需要配置activemq1的位置信息以便进行连接:
    ......
    <transportConnectors>
        <transportConnector name="auto" uri="auto+nio://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600&amp;consumer.prefetchSize=5"/>
    </transportConnectors>
    
    ......
    <!-- 请注意,一定需要192.168.61.138(activemq1)提供了这样的连接协议和端口 -->
    <networkConnectors>
       <networkConnector uri="static:(auto+nio://192.168.61.138:61616)"/>
    </networkConnectors>
    ......

    同理,如果您的ActiveMQ集群规划中有三个ActiveMQ服务节点,那么任何一个节点都应该配置其它两个服务节点的连接方式。在配置格式中使用“,”符号进行分割:

    ......
    <networkConnectors>
        <networkConnector uri="static:(tcp://host1:61616,tcp://host2:61616,tcp://..)"/>
    </networkConnectors>
    ......

    2.3、其他配置属性

    下表列举了在networkConnector标签中还可以使用的属性以及其意义。请特别注意其中的duplex属性。如果只从字面意义理解该属性,则被称为“双工模式”;如果该属性为true,当这个节点使用Network Bridge连接到其它目标节点后,将强制目标也建立Network Bridge进行反向连接。其目的在于让消息既能发送到目标节点,又可以通过目标节点接受消息,但实际上大多数情况下是没有必要的,因为目标节点一般都会自行建立连接到本节点。所以,该duplex属性的默认值为false。

    属性名称          默认值    属性意义
    name bridge 名称
    dynamicOnly false 如果为true, 持久订阅被激活时才创建对应的网路持久订阅。
    decreaseNetworkConsumerPriority false 如果为true,网络的消费者优先级降低为-5。如果为false,则默认跟本地消费者一样为0.
    excludedDestinations empty 不通过网络转发的destination
    dynamicallyIncludedDestinations empty 通过网络转发的destinations,注意空列表代表所有的都转发。
    staticallyIncludedDestinations empty 匹配的都将通过网络转发-即使没有对应的消费者,如果为默认的“empty”,那么说明所有都要被转发
    duplex false 已经进行详细介绍的“双工”属性。
    prefetchSize 1000 设置网络消费者的prefetch size参数。如果设置成0,那么就像之前文章介绍过的那样:消费者会自己轮询消息。显然这是不被允许的。
    suppressDuplicateQueueSubscriptions      false 如果为true, 重复的订阅关系一产生即被阻止(V5.3+ 的版本中可以使用)。
    bridgeTempDestinations true 是否广播advisory messages来创建临时destination。
    alwaysSyncSend false 如果为true,非持久化消息也将使用request/reply方式代替oneway方式发送到远程broker(V5.6+ 的版本中可以使用)。
    staticBridge false 如果为true,只有staticallyIncludedDestinations中配置的destination可以被处理(V5.6+ 的版本中可以使用)。

    以下这些属性,只能在静态Network Connectors模式下使用

    属性名称    默认值    属性意义
    initialReconnectDelay 1000 重连之前等待的时间(ms) (如果useExponentialBackOff为false)
    useExponentialBackOff true 如果该属性为true,那么在每次重连失败到下次重连之前,都会增大等待时间
    maxReconnectDelay 30000 重连之前等待的最大时间(ms)
    backOffMultiplier 2 增大等待时间的系数

    请注意这些属性,并不是networkConnector标签的属性,而是在uri属性中进行设置的,例如:

    uri="static:(tcp://host1:61616,tcp://host2:61616)?maxReconnectDelay=5000&useExponentialBackOff=false"

     三、其他注意事项

    • 关于防火墙:请记得关闭您Linux服务器上对需要公布的IP和端口的限制;

    • 关于hosts路由信息:由于基于组播的动态发现机制,能够找到的是目标ActiveMQ服务节点的机器名,而不是直接找到的IP。所以请设置当前服务节点的hosts文件,以便当前ActiveMQ节点能够通过hosts文件中的IP路由关系,得到机器名与IP的映射:

    # hosts文件
    
    ......
    192.168.61.138          activemq1
    192.168.61.139          activemq2
    ......
    •  关于哪些协议能够被用于进行Network Bridges连接:根据笔者以往的使用经验,只有tcp头的uri格式(openwire协议)能够被用于Network Bridges连接;当然您可以使用auto头,因为其兼容openwire协议;另外,您还可以指定为附加nio头。

     四、一些博文:

    ActiveMQ笔记(3):基于Networks of Brokers的HA方案:http://www.cnblogs.com/leihenqianshang/articles/5623841.html

    ActiveMQ笔记(4):搭建Broker集群(cluster):https://www.cnblogs.com/leihenqianshang/articles/5623858.html

    ActiveMQ笔记(2):基于ZooKeeper的HA方案:http://www.cnblogs.com/leihenqianshang/articles/5623831.html

    架构设计:系统间通信(25)——ActiveMQ集群方案(上):https://blog.csdn.net/yinwenjie/article/details/51124749

    架构设计:系统间通信(26)——ActiveMQ集群方案(下):https://blog.csdn.net/yinwenjie/article/details/51205822

  • 相关阅读:
    Frame内容页向Frame页传值的问题。
    Silverlight 要求使用更新版本
    Siverlight 中RichTextBox 中注入控件无法使用的问题
    PHP_判断是否为数字
    CentOS中vsftp安装与配置
    全面认识F5负载均衡
    如何让php自动进行二级域名泛解析
    【Thinkphp教程】 如何实现URL伪静态
    LVS+heartbeat+ldirectord高可用负载均衡集群解决方案
    ThinkPHP小结
  • 原文地址:https://www.cnblogs.com/arjenlee/p/9303229.html
Copyright © 2020-2023  润新知