因爲最近一個項目併發請求壓力比較大,因此考慮改進架構,引入消息中間件集羣做爲一個緩衝消息隊列,具體需求:
1)將大量的WebService請求報文發送到mq集羣之中,並保持消息前後順序
2)保證每一個消息的可靠性
3)維護MQ服務器的可擴展性html
綜合考慮,決定使用Apache的activemq,activemq是Apache出品,最流行的,能力強勁的開源消息總線。本項目使用的是activemq5.11,activemq5.11要求jdk6+,本次使用jdk7,並引入activemq服務器。
準備三臺服務器:
activemq01 172.16.51.181
activemq01 172.16.51.182
activemq01 172.16.51.183
軟件版本:activemq-5.11.一、zookeeper-3.4.11java
好了,廢話很少說,下面記錄下部署過程:linux
因爲最近一個項目併發請求壓力比較大,因此考慮改進架構,引入消息中間件集羣做爲一個緩衝消息隊列,具體需求: 1)將大量的WebService請求報文發送到mq集羣之中,並保持消息前後順序 2)保證每一個消息的可靠性 3)維護MQ服務器的可擴展性 綜合考慮,決定使用Apache的activemq,activemq是Apache出品,最流行的,能力強勁的開源消息總線。本項目使用的是activemq5.11,activemq5.11要求jdk6+,本次使用jdk7,並引入activemq服務器。 準備三臺服務器: G6-mq01 172.16.51.181 G6-mq02 172.16.51.182 G6-mq03 172.16.51.183 軟件版本:activemq-5.11.一、zookeeper-3.4.11 好了,廢話很少說,下面記錄下部署過程: activemq01機器(172.16.51.181)的部署: 我的運維習慣,會專門建立一個app帳號,用戶部署應用程序。本案例應用程序都部署在/data目錄下,將/data權限設置成app(chown -R app.app /data) [root@G6-mq01 ~]# useradd app [root@G6-mq01 ~]# su - app [app@G6-mq01 ~]$ mkdir /data/software 1、部署zookeeper [app@G6-mq01 software]$ wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.11/zookeeper-3.4.11.tar.gz [app@G6-mq01 software]$ tar -zvxf zookeeper-3.4.11.tar.gz [app@G6-mq01 software]$ mv zookeeper-3.4.11 /data/zookeeper [app@G6-mq01 software]$ cd /data/zookeeper/conf/ [app@G6-mq01 conf]$ cp zoo_sample.cfg.bak zoo.cfg [app@G6-mq01 conf]$ vim zoo.cfg [app@G6-mq01 conf]$ cat zoo.cfg # The number of milliseconds of each tick tickTime=2000 # The number of ticks that the initial # synchronization phase can take initLimit=10 # The number of ticks that can pass between # sending a request and getting an acknowledgement syncLimit=5 # the directory where the snapshot is stored. # do not use /tmp for storage, /tmp here is just # example sakes. dataDir=/data/app/zkdir/data //建立此目錄夾,存放data dataLogDir=/data/app/zkdir/log //建立此目錄夾,存放dat # the port at which the clients will connect clientPort=2181 //zookeeper服務端口 # the maximum number of client connections. # increase this if you need to handle more clients #maxClientCnxns=60 # # Be sure to read the maintenance section of the # administrator guide before turning on autopurge. # # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance # # The number of snapshots to retain in dataDir #autopurge.snapRetainCount=3 # Purge task interval in hours # Set to "0" to disable auto purge feature #autopurge.purgeInterval=1 server.1=172.16.51.181:2888:3888 server.2=172.16.51.182:2888:3888 server.3=172.16.51.183:2888:3888 [app@G6-mq01 conf]$ mkdir -p /data/app/zkdir/data [app@G6-mq01 conf]$ mkdir -p /data/app/zkdir/log 建立myid文件,並寫入與ip地址相稱的服務器編號. [app@G6-mq01 conf]$ cd /data/app/zkdir/data/ [app@G6-mq01 data]$ vim myid //注意,三臺服務器的myid編號不能重複 1 其餘兩臺服務器配置和上面相同,不過myid文件須要寫入不同的id號。兩外兩臺機器的myid能夠分別寫二、3 啓動zookeeper服務: [app@G6-mq01 data]$ /data/zookeeper/bin/zkServer.sh start [app@G6-mq01 data]$ lsof -i:2181 //檢查zookeeper端口起來了沒 查看三臺服務器的zookeeper選舉狀況: [app@G6-mq01 ~]$ /data/zookeeper/bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /data/zookeeper/bin/../conf/zoo.cfg Mode: follower [app@G6-mq02 ~]$ /data/zookeeper/bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /data/zookeeper/bin/../conf/zoo.cfg Mode: leader [app@G6-mq03 ~]$ /data/zookeeper/bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /data/zookeeper/bin/../conf/zoo.cfg Mode: follower 2、部署activemq [app@G6-mq01 software]$ wget http://archive.apache.org/dist/activemq/5.11.1/apache-activemq-5.11.1-bin.tar.gz [app@G6-mq01 software]$ tar -zvxf apache-activemq-5.11.1-bin.tar.gz [app@G6-mq01 software]$ mv apache-activemq-5.11.1 /data/activemq [app@G6-mq01 software]$ cd /data/activemq/conf/ [app@G6-mq01 conf]$ cp activemq.xml activemq.xml.bak [app@G6-mq01 conf]$ vim activemq.xml ........ # 須要修改brokerName爲某個字段值(注:不可以使用默認的localhost),這個是mq集羣名稱。 # 一個集羣內的全部的mq的brokerName爲同一個值。也就是說兩臺服務器的這個配置也要是同樣的。 # 加上useJmx="true"的屬性,用做server的負載均衡使用。 <broker xmlns="http://activemq.apache.org/schema/core" brokerName="mq-cluster01" dataDirectory="${activemq.data}" useJmx="true"> ........ #將kahaDB 給註釋掉,新增replicatedLevelDB,其中replicas表示爲一個集羣裏面有幾個mq節點 #bind的端口號改成集羣端口,若是爲0,則會隨意分配一個端口給mq節點,不方便查詢,因此最好是分配一個固定的端口。要是有第二個集羣,此端口最好別同樣。 #zkAddress爲zookeeper所在服務器的ip及客戶端端口,hostname爲mq所在服務器的地址,若是有zkpassword,則填寫,不然不要填寫。 #zkPath的路徑每一個集羣不同,同一個集羣配成同樣的,例如第二個集羣zkPath="/activemq2/leveldb-stores"。 <!-- <persistenceAdapter> <kahaDB directory="${activemq.data}/kahadb"/> </persistenceAdapter> --> <persistenceAdapter> <replicatedLevelDB directory="${activemq.data}/leveldb" replicas="3" #表示這個activemq集羣內有三個mq節點 bind="tcp://0.0.0.0:62621" #這個最好別用tcp://0.0.0.0:0配置,若是端口爲0,則會隨意分配一個端口。這裏用固定的62621端口。 zkAddress="172.16.51.181:2181,172.16.51.182:2181,172.16.51.183:2181" zkPassword="" hostname="172.16.51.181" #這個配置成各個mq節點的ip地址 sync="local_disk" zkPath="/activemq/leveldb-stores"/> </persistenceAdapter> ........ # 下面爲ActiveMQ的內存分配信息。這一段默承認以不改。 # memoryUsage:表示全部隊列對象佔用的內存大小爲70mb; <systemUsage> <systemUsage> <memoryUsage> <memoryUsage percentOfJvmHeap="70" /> </memoryUsage> <storeUsage> <storeUsage limit="100 gb"/> </storeUsage> <tempUsage> <tempUsage limit="50 gb"/> </tempUsage> </systemUsage> </systemUsage> ........ #下面配置的61616端口便是activemq的服務端口 #將name爲amqp、stomp、mqtt、ws幾個給註釋掉,只留下name爲openwire的方式(其中ip能夠改成mq所在服務器的ip) <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <!-- <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> --> 下面開始啓動activem [app@G6-mq01 conf]$ /data/activemq/bin/activemq start INFO: Loading '/data/activemq/bin/env' INFO: Using java '/usr/bin/java' INFO: Starting - inspect logfiles specified in logging.properties and log4j.properties to get details INFO: pidfile created : '/data/activemq/data/activemq.pid' (pid '12229') 查看端口啓動狀況 [app@G6-mq01 conf]$ lsof -i:61616 #這個是active的服務端 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 12229 app 137u IPv6 42501 0t0 TCP *:61616 (LISTEN) [app@G6-mq01 conf]$ lsof -i:8161 #這個是active的管理端口,在jetty.xml文件裏配置的 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 12229 app 131u IPv6 42512 0t0 TCP *:patrol-snmp (LISTEN) 另外兩臺服務器配置和上面相似,只需修改本身的ip地址便可。 注意: 由於使用zookeeper作負載均衡,三臺服務器中只會有一臺是master,其餘兩臺處於等待狀態,因此只有其中一臺提供服務。 因此其餘兩臺服務器雖然active程序啓動了,可是61616服務端口和8161管理端口是關閉等待狀態(即也就是說這兩臺節點的這兩個端口不會起來,只有當master節點故障時,他們中的一個節點的這兩個端口才會接着起來) 只有當這臺提供服務的服務器宕機之後,纔會經過zookeeper選舉出另外的一臺頂替上來,因此其餘幾個ip地址是打不開的,只有一臺能打開! 在代碼裏,使用failover進行配置的,以下: mq.broker.url=failover:(tcp://172.16.51.181:61616,tcp://172.16.51.182:61616,tcp://172.16.51.183:61616)?initialReconnectDelay=1000
在瀏覽器裏輸入下面三個訪問地址(默認只有一個master狀態的地址能打開),默認用戶名和密碼都是adminmacos
http://172.16.51.181:8161/admin/queues.jsp http://172.16.51.182:8161/admin/queues.jsp http://172.16.51.183:8161/admin/queues.jsp 以上三個地址,默認只能有一個打開,也就是master角色的這個能打開,當這個機器宕機或activemq關閉時,其餘兩臺機器中的一個才能接管服務。
------------------------------------------補充說明--------------------------------------------apache
1)修改acticemq管理端口 將8161改成其餘端口 [app@G6-mq01 ~]$ cd /data/activemq/conf/ [app@G6-mq01 conf]$ cat jetty.xml |grep 8161 <property name="port" value="8161"/> kill掉activemq當前的pid,而後start便可 [app@G6-mq01 ~]$ ps -ef|grep activemq|grep -v grep|awk '{print $2}'|xargs kill -9 [app@G6-mq01 ~]$ cd /data/activemq/bin/ [app@G6-mq01 bin]$ ls activemq activemq-admin activemq.jar diag env linux-x86-32 linux-x86-64 macosx wrapper.jar [app@G6-mq01 bin]$ ./activemq start 2) 修改activemq管理界面登錄的用戶名和密碼 默認的用戶名和密碼爲admin,內部使用還好,但若是是對外服務,安全考慮,最好仍是將用戶名和密碼修改下。 須要在activemq.xml文件中的</shutdownHooks>下新增下面內容,用於消息鏈接身份認證的用戶名和密碼。 此處引用的是credentials.properties文件夾下面的activemq.username、activemq.password值。 通常寫爲activemq.username=system、activemq.password=manager。 [app@G6-mq01 conf]$ cat activemq.xml ........ <plugins> <simpleAuthenticationPlugin> <users> <authenticationUser username="${activemq.username}" password="${activemq.password}" groups="users,admins"/> </users> </simpleAuthenticationPlugin> </plugins> [app@G6-mq01 conf]$ cat credentials-enc.properties #這個文件默認就行,高版本默認的就是用戶名就是system activemq.username=system activemq.password=ENC(mYRkg+4Q4hua1kvpCCI2hg==) #密碼這裏是加密的。 [app@G6-mq01 conf]$ cat jetty-realm.properties ......... username: password [,rolename ...] system: manager, admin # admin: admin, admin # user: user, user 而後重啓activemq服務便可,這樣訪問http://172.16.51.181:8161/admin/queues.jsp的時候,登錄用戶名和密碼就是system和manager。 3)若是是部署單機activemq。則上面就不須要部署zookeeper服務,直接安裝activemq,配置默認,而後啓動activemq。 接着訪問http://172.16.51.181:8161/admin/queues.jsp (登錄用戶名和密碼:admin/admin)便可。