搭建RocketMQ

RocketMQ搭建步驟

開發環境

  • 64位 centos7(虛擬機,1G內存)
  • 64位 jdk1.8
  • maven 3.5.0
  • Git
  • tomcat(用於啓動rocketmq-console)
  • rocketmq 3.2.6(最好選擇maven倉庫中已有的版本,保持客戶端依賴的jar包和服務器版本一致)
  • rocketmq-console

環境變量配置

vi /etc/profile 打開文件配置如下:

JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
JRE_HOME=$JAVA_HOME/jre
CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
M2_HOME=/usr/maven/
ROCKETMQ_HOME=/usr/rocketmq
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin:$M2_HOME/bin:$ROCKETMQ_HOME/bin
export JAVA_HOME JRE_HOME CLASS_PATH M2_HOME ROCKETMQ_HOME PATH
export NAMESRV_ADDR=127.0.0.1:9876
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

source /etc/profile 使配置文件立即生效

防火牆配置

宿主機需要遠程訪問虛擬機的rocketmq服務和web服務,需要開放相關的端口號,簡單粗暴的方式是直接關閉防火牆

service iptables stop 關閉防火牆
service iptables status 查看防火牆的狀態
service iptables start 啓動防火牆
  • 1
  • 2
  • 3
  • 4

或者爲了安全,只開放特定的端口號,如8080、9876、10911等等,此處不再贅述。

安裝、啓動RocketMQ

1.下載和安裝

cd /usr
wget https://github.com/alibaba/RocketMQ/releases/download/v3.2.6/alibaba-rocketmq-3.2.6.tar.gz
tar -zxvf alibaba-rocketmq-3.2.6.tar.gz
mv alibaba-rocketmq-3.2.6 rocketmq
  • 1
  • 2
  • 3
  • 4
  • 5

cd rocketmq/bin 進入rocketmq核心命令文件目錄

2.設置可執行權限

chmod +x mqadmin mqbroker mqfiltersrv mqshutdown  mqnamesrv
  • 1
  • 2

3.修改jvm參數

vim修改runserver.sh和runbroker.sh的jvm參數如下(根據虛擬機內存大小設置,超出內存大小可能會報錯):
JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m -Xmn256m -XX:PermSize=128m -XX:MaxPermSize=320m"
  • 1
  • 2
  • 3

4.啓動nameserver

nohup sh mqnamesrv &
  • 1
  • 2

5.配置broker

(1)創建broker配置文件

mkdir ../conf/me-2m-2s-async/
sh mqbroker -m >../conf/me-2m-2s-async/broker.p
  • 1
  • 2
  • 3

(2)修改brokerIP

vi ../conf/me-2m-2s-async/broker.p
brokerIP1=192.168.x.x  顯示指定爲虛擬機的外網IP,不要用localhost和127.0.0.1,因爲遠程主機會根據brokerIP1指定的地址去訪問broker
  • 1
  • 2
  • 3

6.啓動broker

nohup sh mqbroker -n localhost:9876 -c ../conf/me-2m-2s-async/broker.p &
  • 1
  • 2

7.檢查nameserver和broker是否啓動成功

執行jps,輸出以下進程表示啓動成功

8464 NamesrvStartup
8618 BrokerStartup
  • 1
  • 2
  • 3

或者,查看nuhup.out日誌文件,有如下信息表示啓動成功

The Name Server boot success.
The broker[localhost.localdomain, 192.168.x.x:10911] boot success. and name server is localhost:9876
  • 1
  • 2
  • 3

或者,啓動rocketmq自帶的Producer和Consumer程序,若可正常發送和消費消息,則表示服務啓動成功

bash tools.sh com.alibaba.rocketmq.example.quickstart.Producer #生產者
bash tools.sh com.alibaba.rocketmq.example.quickstart.Consumer #消費者
  • 1
  • 2
  • 3

8.關閉nameserver和broker的方法

sh mqshutdown broker
sh mqshutdown namesrv
  • 1
  • 2
  • 3

安裝、啓動rocketmq-console

wget https://github.com/duomu/rocketmq-console/raw/master/rocketmq-console.war 下載
將rocketmq-console.war放在/usr/tomcat/webapps目錄下
sh /usr/tomcat/bin/startup.sh  啓動tomcat
  • 1
  • 2
  • 3
  • 4

虛擬機本地訪問http://localhost:8080/rocketmq-console,顯示如下頁面表示啓動成功 
這裏寫圖片描述

宿主機遠程訪問http://192.168.x.x:8080/rocketmq-console,若無法訪問,請檢查防火牆是否關閉或者是否開放了8080端口號。

編寫測試程序

在宿主機(windows)上編寫如下測試程序:

依賴配置

//此處只列出mq相關的依賴
<dependency>
    <groupId>com.alibaba.rocketmq</groupId>
    <artifactId>rocketmq-client</artifactId>
    <version>3.2.6</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

創建生產者

package com.fuscent.infoquery.practice.rocketmq;

import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.alibaba.rocketmq.client.producer.SendResult;
import com.alibaba.rocketmq.common.message.Message;
import org.apache.log4j.Logger;

/**
 * @author:duomu
 * @date:2017/8/4 18:09
 */
public class MqProducer {
    private static Logger logger = Logger.getLogger(MqProducer.class);
    public static void main(String[] args) {
        DefaultMQProducer producer = new DefaultMQProducer("Producer");
        producer.setNamesrvAddr("192.168.229.132:9876");
        try {
            producer.start();
            logger.info("producer啓動成功");
            for (int i = 0; i < 5; i++) {
                Message msg = new Message("TopicA", "tagA", "OrderID188", "Hello world".getBytes());
                SendResult result = producer.send(msg);
                logger.info("id:" + result.getMsgId() + " result:" + result.getSendStatus());
            }
        } catch (Exception e) {
            logger.error("發送消息失敗,Exception error:" + e);
        } finally {
            producer.shutdown();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

創建消費者

package com.fuscent.infoquery.practice.rocketmq;

import com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;
import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import com.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.common.consumer.ConsumeFromWhere;
import com.alibaba.rocketmq.common.message.Message;
import com.alibaba.rocketmq.common.message.MessageExt;
import org.apache.log4j.Logger;
import java.util.List;

/**
 * @author:duomu
 * @date:2017/8/4 18:09
 */
public class MqConsumer {
    private static Logger logger = Logger.getLogger(MqConsumer.class);

    public static void main(String[] args) {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("PushConsumer_yll");
        consumer.setNamesrvAddr("192.168.229.132:9876");
        try {
            consumer.subscribe("TopicA", "tagA||tagB");//可訂閱多個tag,但是一個消息只能有一個tag
            consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
            consumer.registerMessageListener(new MessageListenerConcurrently() {
                @Override
                public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
                    Message msg = list.get(0);
                    logger.info(msg.toString());
                    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                }
            });
            consumer.start();
            logger.info("consumer啓動成功");
        } catch (MQClientException e) {
            logger.error("消費者訂閱消息失敗,error:" + e);
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

測試生成者和消費者

啓動生成者

這裏寫圖片描述

啓動消費者

這裏寫圖片描述

總結

前人栽樹,後人乘涼,在baidu+google了n篇文章後,終於把rocketmq搭建成功了,雖然只是單機配置,但是把該踩的坑都踩了,集羣搭建應該只是多配幾臺服務而已,後續再研究啦~~~

坑1

在github上下載了最新的rocketmq4.1.0,後來發現maven中央倉庫還沒有4.1.0的rocketmq-client依賴包,後來下載了3.5.8,也沒有調成功,索性下載一個比較早期的版本,選了3.2.6,我們公司用的3.2.4,比我們公司的早一點點應該不會太差。。。

坑2

nameserver和broker啓動成功,宿主機上的生產者發送消息失敗,報如下錯誤,且指向錯誤碼33/44/50:

com.alibaba.rocketmq.client.exception.MQClientException:Send [1] times, still failed, cost [75]ms,...
  • 1
  • 2

出現這個問題首先要查看虛擬機本地的producer是否可以正常發送消息,如果本地收發消息正常,那麼一定遠程訪問的過程中出了問題,可能是端口號沒開放,也可能是IP地址映射有問題。

對於端口號,我已經確定了n遍,防火牆是關閉的,最初還沒有考慮到IP地址的問題,所以百思不得其解,從阿里官方渠道獲取了錯誤33/44/50的解決方案,試了一下也沒用,把rocketmq3.2.6源碼裏面的Producer跑了一下也是報那個錯誤,錯誤44的說明裏寫着可能是producer沒有正確連接到NameServer,我知道沒有連接成功,可是防火牆我都關閉了還能有什麼原因呢。

這裏寫圖片描述

搗鼓了大半天,就卡在這個問題上了,我想我一定是漏掉了什麼,反反覆覆看38/44/50的錯誤說明,直到看到錯誤50說明裏面的這一句話:

這裏寫圖片描述

然後我注意到下面這個嵌套錯誤,debug了一下,也沒看出什麼,當時我還以爲這個ip是虛擬機的局域網ip

這裏寫圖片描述

接着就baidu+google,偶然google出一篇思路別具一格的文章,說rocketmq自動識別網絡出錯,要把其他網絡關掉,我之前學習docker的時候的確在虛擬機上配了docker的網絡。

這裏寫圖片描述

然後就嘗試關掉docker的網絡(172.17.0.1),可是關掉了還是照樣報上面的錯誤啊。。。

真的沒有辦法了,今天早晨來了突然想到,能夠訪問外網ip不能訪問局域網ip,ping一下看看吧,果然局域網ip ping不通,由於對網絡、虛擬機瞭解的不深,我就去求教網絡童鞋了,問宿主機怎麼能夠訪問虛擬機的局域網ip(我用的NAT模式),網絡童鞋說你用橋接模式吧,當時心中暗喜,心想吼吼我的大難題就要這麼簡單的解決了,網絡童鞋走後,我就試了一下,麻蛋爲什麼用橋接模式分了新的ip(172.16.2.129),還是報上面那個172.17.0.1的錯誤。。

第一次搭rocketmq,想盡快調通,基本上都是用的默認配置,而且默認配置一般不會有問題啊,自己寫配置才容易出錯,然鵝萬能的百度告訴我我之前先入爲主的觀念是錯的,我想這應該是終極解決方案了吧。。

這裏寫圖片描述

原來broker自動尋的地址是172.17.0.1,而且深深的刻在了默認配置文件裏,雖然我關掉了這個網絡,配置文件裏還是這個地址,然後我重新寫了個配置文件,強制指定broker所在的機器ip爲192.168.x.x,重啓服務,大功告成!

和局域網ip能否ping通無關,我把網絡連接改回了NAT模式,感謝網絡童鞋的幫忙,我要好好補一下網絡和虛擬機的知識了。。。

參考資料

附上最有價值的幾個~~ 
http://rocketmq.apache.org/docs/quick-start/ 官方資料,搭建mq之前最好把User Guide都看一遍 
https://firsh.me/2017/07/19/rocketmq-p-c/ 
https://my.oschina.net/xcafe/blog/814135 坑2的終極解決方案 
http://www.cnblogs.com/badboyf/p/6611774.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章