0:說明java
ActiveMQ 5.9.0新推出的主從實現,基於zookeeper來選舉出一個master,其餘節點自動做爲slave實時同步消息。由於有實時同步數據的slave的存在,master不用擔憂數據丟失,因此leveldb會優先採用內存存儲消息,異步同步到磁盤,因此該方式的activeMQ讀寫性能最好由於選舉機制要超過半數,因此最少須要3臺節點,才能實現高可用。若是集羣是兩臺則master失效後slave會不起做用,因此集羣至少三臺。此種方式僅實現主備功能,避免單點故障,沒有負載均衡功能。web
1:環境準備spring
IP
192.168.3.10 server1
192.168.3.11 server2
192.168.3.12 server3apache
安裝軟件信息:json
apache-activemq-5.13.0-bin.tar.gzvim
zookeeper-3.5.2-alpha.tar.gzapp
ZooInspector.zip負載均衡
2:搭建Zookeeper集羣異步
(1)將zookeeper-3.5.2-alpha.tar.gz文件解壓到/home/wzh/zk目錄;tcp
(2)將zoo_sample.cfg複製一份爲 zoo.cfg,並修改其配置信息
wzh@hd-master:~/zk/zookeeper-3.5.2-alpha/conf$ cp zoo_sample.cfg zoo.cfg
wzh@hd-master:~/zk/zookeeper-3.5.2-alpha/conf$vim zoo.cfg
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/tmp/zookeeper clientPort=2181 server.1=192.168.3.10:2888:3888 server.2=192.168.3.11:2888:3888 server.3=192.168.3.11:2888:3888
(3)建立/tmp/zookeeper目錄
在該目錄下建立名爲myid的文件,內容爲1(這個值隨server而改變)
(4)將server1上的/home/wzh/zk/zookeeper-3.5.2-alpha文件夾複製到server2,server3,而後建立/tmp/zookeeper目錄
在該目錄下建立名爲myid的文件,內容爲2
(5)啓動zookeeper
[192.168.3.10]
wzh@hd-master:~/zk/zookeeper-3.5.2-alpha/bin$ ./zkServer.sh start ZooKeeper JMX enabled by default Using config: /home/wzh/zk/zookeeper-3.5.2-alpha/bin/../conf/zoo.cfg Starting zookeeper ... STARTED
[192.168.3.11]
wzh@hd-slave1:~/zk/zookeeper-3.5.2-alpha/bin$ ./zkServer.sh start ZooKeeper JMX enabled by default Using config: /home/wzh/zk/zookeeper-3.5.2-alpha/bin/../conf/zoo.cfg Starting zookeeper ... STARTED
[192.168.3.12]
wzh@hd-slave2:~/zk/zookeeper-3.5.2-alpha/bin$ ./zkServer.sh start ZooKeeper JMX enabled by default Using config: /home/wzh/zk/zookeeper-3.5.2-alpha/bin/../conf/zoo.cfg Starting zookeeper ... STARTED
3:搭建ActiveMQ集羣
(1)將apache-activemq-5.13.0-bin.tar.gz解壓到/home/wzh/amq
(2)修改activemq.xml配置文件
【1】將broker節點的brokerName設置爲wzhamq
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="wzhamq" dataDirectory="${activemq.data}">
【2】將persistenceAdapter的持久化方式選用replicatedLevelDB,將kahaDB方式註釋掉
<persistenceAdapter> <!-- <kahaDB directory="${activemq.data}/kahadb"/> --> <replicatedLevelDB directory="${activemq.data}/leveldb" replicas="3" bind="tcp://0.0.0.0:0" zkAddress="192.168.3.10:2181,192.168.3.11:2181" hostname="192.168.3.10" sync="local_disk" zkPath="/activemq/leveldb-stores"/> </persistenceAdapter>
將apache-activemq-5.13.複製到11,12機器
wzh@hd-master:~/amq$ scp -r apache-activemq-5.13.0/ wzh@192.168.3.11:/tmp
修改配置文件中的hostname="192.168.3.11"
修改配置文件中的hostname="192.168.3.12"
(3)啓動ActiveMQ
wzh@hd-master:~/amq$ ./apache-activemq-5.13.0/bin/activemq status INFO: Loading '/home/wzh/amq/apache-activemq-5.13.0//bin/env' INFO: Using java '/opt/java/jdk1.8.0_91/bin/java' ActiveMQ is running (pid '2031') wzh@hd-master:~/amq$
依次啓動192.168.3.11,192.168.3.12機器
4:集羣管理
(1)經過使用ZooInspector工具查看zookeeper集羣狀況
(2)http://192.168.3.10:8161/admin/ 默認用戶名與口令爲admin登陸ActiveMQ管理端
5:經過Spring-boot操做ActiveMQ JMS
(1)經過gradle構建Spring-boot應用,在 gradle文件中增長
dependencies { compile('org.springframework.boot:spring-boot-starter-activemq') compile('org.springframework.boot:spring-boot-starter-web') testCompile('org.springframework.boot:spring-boot-starter-test') }
(2)application中增長如下配置
spring.activemq.broker-url=failover:(tcp://192.168.3.10:61616,tcp://192.168.3.11:61616,tcp://192.168.3.12:61616) spring.activemq.in-memory=true spring.activemq.pool.enabled=false spring.activemq.user=admin spring.activemq.password=admin
(3)JMS消息發送
@Service public class Producer { @Autowired private JmsMessagingTemplate jmsTemplate; public void sendMessage(Destination destination, final String message){ jmsTemplate.convertAndSend(destination, message); } }
(4)JMS消息接收
@Component public class Consumer { @JmsListener(destination = "test.queue") public void receiveQueue(String text){ System.out.println("Consumer收到的報文爲:"+text); } }
(5)測試
@RestController @RequestMapping( value = "/test", headers = "Accept=application/json", produces = "application/json;charset=utf-8" ) public class TestCtrl { @Autowired Producer producer; Destination destination = new ActiveMQQueue("test.queue"); @RequestMapping( value = "/say/{msg}/to/{name}", method = RequestMethod.GET ) public Map<String, Object> say(@PathVariable String msg, @PathVariable String name){ Map<String, Object> map = new HashMap<>(); map.put("msg", msg); map.put("name", name); producer.sendMessage(destination, msg); return map; } }
(6)進入ActiveMQ管理控制檯建立一個消息隊列
test.queue
(7)經過POSTMAN進行測試
2017-08-03 08:10:44.928 INFO 12820 --- [ActiveMQ Task-3] o.a.a.t.failover.FailoverTransport : Successfully reconnected to tcp://192.168.3.10:61616
2017-08-03 08:11:08.854 INFO 12820 --- [ActiveMQ Task-1] o.a.a.t.failover.FailoverTransport : Successfully connected to tcp://192.168.3.10:61616
Consumer收到的報文爲:hello
2017-08-03 08:43:39.464 INFO 12820 --- [ActiveMQ Task-1] o.a.a.t.failover.FailoverTransport : Successfully connected to tcp://192.168.3.10:61616
Consumer收到的報文爲:hello
(8)目前系統鏈接的是10,若是此時將10集羣Down掉,系統會理解選擇一臺slave做爲master提供服務,從而啓動案例主備的效果。