消息中間件——RocketMQ(一) 環境搭建(完整版)

求關注

環境搭建

每章一點正能量:自我控制是最強者的本能?!挷{

前言

最近在學習消息中間件——RocketMQ,打算把這個學習過程記錄下來。此章主要介紹環境搭建。此次主要是單機搭建(條件有限),包括在Windows、Linux環境下的搭建,以及console監控平臺搭建,最后加一demo驗證一下。

環境準備

在搭建RocketMQ之前,請先確保如下環境已經搭建完畢

  • Java環境(我的JDK1.8)
  • Maven環境(我的3.6.1目前最新版)
  • Git環境

沒有搭建的同學走傳送門:

JDK環境搭建: JAVA8環境搭建
Maven環境搭建: Windows環境下使用Nexus 3.X 搭建Maven私服及使用介紹
Git環境搭建:Git環境搭建及配置


1. Windows環境下搭建

1.1 下載

官方網站:http://rocketmq.apache.org/

官網

目前最新版的是V4.5.0,點擊進去。


rocketmq-all-4.5.0-bin-release.zip

選擇下載 rocketmq-all-4.5.0-bin-release.zip。彈出另外一個頁面,這里選擇rocketmq-all-4.5.0-bin-release.zip進行下載。


rocketmq-all-4.5.0-bin-release.zip

下載成功后,選擇一個目錄放好并解壓。
解壓

1.2 修改JVM配置

以上操作完畢之后,進入目錄bin目錄,我這里是
H:\rocketmq\rocketmq-all-4.5.0-bin-release\rocketmq-all-4.5.0-bin-release\bin
找到runserver.cmdrunbroker.cmd中的JAVA_OPT。

在這里插入圖片描述

原JAVA_OPT:

set "JAVA_OPT=%JAVA_OPT% -server -Xms2g -Xmx2g -Xmn1g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"

將 Xms Xmx 這兩個值改小一些,改為1g,如:

set "JAVA_OPT=%JAVA_OPT% -server -Xms1g -Xmx1g -Xmn1g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"

自己根據虛擬機內存大小設置,超出內存大小可能會報錯。

1.3 配置環境變量

上述步驟執行完畢后,我們需要將RocketMQ安裝目錄的bin目錄配置到環境變量中。

RocketMQ_HOME

1.4 啟動

以上配置都完成,接下來就是啟動過程。中間有點坑,請務必按步驟安裝。

在RocketMQ安裝目錄的bin目錄下,執行命令cmd:

我的目錄:

H:\rocketmq\rocketmq-all-4.5.0-bin-release\rocketmq-all-4.5.0-bin-release\bin

可以通過shift+鼠標右擊 觸發cmd窗口選項。也可以通過win+R 在窗口輸入cmd,進入cmd窗口后移動到bin目錄下。

1.4.1 啟動NAMESERVER

  • 執行命令:start mqnamesrv.cmd

成功后會彈出提示框,此框勿關閉。


success

1.4.3 啟動BROKER

  • 執行命令:‘start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true’

注意:假如彈出提示框提示‘錯誤: 找不到或無法加載主類 xxxxxx’。打開runbroker.cmd,然后將‘%CLASSPATH%’加上英文雙引號。

失敗

打開 runbroker.cmd 進行修改
原:

set "JAVA_OPT=%JAVA_OPT% -cp %CLASSPATH%"

修改后:

set "JAVA_OPT=%JAVA_OPT% -cp "%CLASSPATH%""
修改后

再次執行命令:
啟動成功!

成功

這時候一共有三個窗口。


2. 安裝Console監控

2.1 下載

下載地址:https://github.com/apache/rocketmq-externals

下載完后如圖所示:選擇——>rocketmq-console


rocketmq-console

2.2 配置

下載完成之后,進入‘rocketmq-externals\rocketmq-console\src\main\resources’文件夾,打開‘application.properties’進行配置。


修改配置

修改配置

2.2 編譯啟動

進入‘\rocketmq-externals\rocketmq-console’文件夾,執行‘mvn clean package -Dmaven.test.skip=true’,編譯生成。中間有個比較慢的下載過程需要等待。


編譯

編譯成功之后,cmd進入‘target’文件夾,執行‘java -jar rocketmq-console-ng-1.0.1.jar’,啟動‘rocketmq-console-ng-1.0.1.jar’。

rocketmq-console-ng-1.0.1.jar

rocketmq-console-ng-1.0.1.jar

2.3 查看

訪問地址:localhost:8082


界面

2.Linux環境下搭建

2.1 環境準備

  • Java環境
  • Maven環境

2.1.1 Linux環境搭建Jdk

下載JDK:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

下載需要的版本:

下載地址

上傳到創建的目錄/usr/java

解壓命令

tar -zxvf jdk-8u181-linux-x64.tar.gz

配置環境變量命令

vim /etc/profile
 
JAVA_HOME=/usr/java/jdk1.8.0_161
JRE_HOME=/usr/java/jdk1.8.0_161/jre
CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export JAVA_HOME JRE_HOME CLASS_PATH PATH
 
source /etc/profile

驗證是否成功命令


java -version

JDK安裝成功

按照以上操作,完成JDK的安裝。接下來安裝Maven環境。

2.1.2 Linux環境搭建Maven

  1. 下載命令:

wget http://mirror.bit.edu.cn/apache/maven/binaries/apache-maven-3.2.2-bin.tar.gz

  1. 解壓命令:

tar -zxvf apache-maven-3.2.2-bin.tar.gz

  1. 配置Maven環境命令:

vim /etc/profile
 
#配置maven環境變量
export MAVEN_HOME=/usr/maven/apache-maven-3.5.4
export MAVEN_HOME
export PATH=$PATH:$MAVEN_HOME/bin
 
source /etc/profile

  1. 驗證是否成功命令:

mvn -v


Maven安裝成功

2.2 下載RocketMQ

  1. 下載命令:

wget http://mirrors.hust.edu.cn/apache/rocketmq/4.4.0/rocketmq-all-4.4.0-source-release.zip

  1. 解壓命令:
unzip rocketmq-all-4.4.0-source-release.zip

[圖片上傳失敗...(image-792c35-1557466617990)]

  1. 構建二進制文件命令

進入解壓后的文件目錄。

mvn -Prelease-all -DskipTests clean install -U

構建二進制成功

2.3 修改JVM配置

同Windows環境一樣,修改JVM配置。
移動到目錄 /home/rocketmq/rocketmq-all-4.4.0/distribution/target/apache-rocketmq/bin 中。編輯bin目錄下runserver.shrunbroker.sh文件。

根據個人虛擬機大小進行修改


vim runserver.sh 
JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m -XX:PermSize=64m -XX:MaxPermSize=128m"
vim runbroker.sh
JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m -XX:PermSize=64m -XX:MaxPermSize=128m"

修改JVM配置

2.4 配置RocketMQ環境變量

分別執行如下命令:

#修改環境變量
vim /etc/profile

export ROCKETMQ=/home/rocketmq/rocketmq-all-4.4.0/distribution/target/apache-rocketmq
export PATH=$PATH:$ROCKETMQ/bin

#更新配置
source /etc/profile

[圖片上傳失敗...(image-18d4c3-1557466617991)]

2.5 啟動NAMESERVER

依然在之前的目錄 /home/rocketmq/rocketmq-all-4.4.0/distribution/target/apache-rocketmq

  • 執行命令:
##啟動命令
nohup sh bin/mqnamesrv  >/dev/null 2>&1 &

##查看日志
tail -f ~/logs/rocketmqlogs/namesrv.log

[圖片上傳失敗...(image-88d435-1557466617991)]

可以看圖已經成功了!

2.6 啟動BROKER

  • 執行命令:
##啟動命令
nohup sh bin/mqbroker -n localhost:9876 &

##查看日志
tail -f ~/logs/rocketmqlogs/broker.log

[圖片上傳失敗...(image-62e759-1557466617991)]

注意防火墻,如果端口連接失敗,注意開通。

2.7 關閉命令

sh bin/mqshutdown broker    //停止 broker
 
sh bin/mqshutdown namesrv   //停止 nameserver

2.8 配置Console監控平臺

同Windows平臺搭建

2.8.1 啟動Console

我這里直接將Windows平臺打包好的jar包直接丟到了Linux系統中

  • 啟動命令:
java -jar rocketmq-console-ng-1.0.1.jar

[圖片上傳失敗...(image-435d8d-1557466617991)]

2.8.2 訪問Console管理界面

訪問地址:http://192.168.220.72:8082

[圖片上傳失敗...(image-635ed8-1557466617991)]


3. Console監控平臺說明

這里不做過多介紹,可以參考以下文章

官網地址:https://github.com/apache/rocketmq-externals/blob/master/rocketmq-console/doc/1_0_0/UserGuide_CN.md

其他博客地址:https://guozh.net/rocketmqzhiconsolejiankongpingtaishiyongxiangjiesan/

3. 案例測試

案例整合環境:SpringBoot環境
案例來源于網絡

3.1 pom.xml文件


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.coderprogramming.rocketmq</groupId>
    <artifactId>rocketmq</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>rocketmq</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-spring-boot-starter</artifactId>
            <version>2.0.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3.2 Producer生產者


**
 * @Description: 生產者
 * @author Coder編程
 * @date 2019/5/8 17:08
 */

@Component
public class Producer {
    /**
     * 生產者的組名
     */
    @Value("${apache.rocketmq.producer.producerGroup}")
    private String producerGroup;

    /**
     * NameServer 地址
     */
    @Value("${apache.rocketmq.namesrvAddr}")
    private String namesrvAddr;


    public void orderedProducer() throws MQClientException, InterruptedException {
        /**
         * 一個應用創建一個Producer,由應用來維護此對象,可以設置為全局對象或者單例
         * 注意:ProducerGroupName需要由應用來保證唯一
         * ProducerGroup這個概念發送普通的消息時,作用不大,但是發送分布式事務消息時,比較關鍵,
         * 因為服務器會回查這個Group下的任意一個Producer
         */
        DefaultMQProducer producer = new DefaultMQProducer(producerGroup);
        producer.setNamesrvAddr(namesrvAddr);
        /**
         * Producer對象在使用之前必須要調用start初始化,初始化一次即可 注意:切記不可以在每次發送消息時,都調用start方法
         */
        producer.start();


        /**
         * 下面這段代碼表明一個Producer對象可以發送多個topic,多個tag的消息。
         * 注意:send方法是同步調用,只要不拋異常就標識成功。但是發送成功也可會有多種狀態
         * 例如消息寫入Master成功,但是Slave不成功,這種情況消息屬于成功,但是對于個別應用如果對消息可靠性要求極高,
         * 需要對這種情況做處理。另外,消息可能會存在發送失敗的情況,失敗重試由應用來處理。
         */
        try {
            for (int i = 0; i < 10; i++) {
                    Message msg = new Message("Topic1",// topic
                            "TagA",// tag
                            "001",// key
                            ("Send Msg:Hello MetaQ1").getBytes());// body
                    SendResult sendResult = producer.send(msg);
                    System.out.println(sendResult);

                    Message msg2 = new Message("Topic2",// topic
                            "TagB",// tag
                            "002",// key
                            ("Send Msg:Hello MetaQ2").getBytes());// body
                    SendResult sendResult2 = producer.send(msg2);
                    System.out.println(sendResult2);


                    Message msg3 = new Message("Topic3",// topic
                            "TagC",// tag
                            "003",// key
                            ("Send Msg:Hello MetaQ3").getBytes());// body
                    SendResult sendResult3 = producer.send(msg3);
                    System.out.println(sendResult3);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        /**
         * 應用退出時,要調用shutdown來清理資源,關閉網絡連接,從MetaQ服務器上注銷自己
         * 注意:我們建議應用在JBOSS、Tomcat等容器的退出鉤子里調用shutdown方法
         */
        producer.shutdown();
    }

}


3.3 Consumer消費者



/**
 * @Description: 消費者
 * @author Coder編程
 * @date 2019/5/8 17:08
 */

@Component
public class Consumer {

    /**
     * 生產者的組名
     */
    @Value("${apache.rocketmq.producer.producerGroup}")
    private String producerGroup;

    /**
     * NameServer 地址
     */
    @Value("${apache.rocketmq.namesrvAddr}")
    private String namesrvAddr;


    /**
     * 當前例子是PushConsumer用法,使用方式給用戶感覺是消息從RocketMQ服務器推到了應用客戶端。
     * 但是實際PushConsumer內部是使用長輪詢Pull方式從Broker拉消息,然后再回調用戶Listener方法
     */
    public void orderedConsumer() throws InterruptedException,MQClientException {
        /**
         * 一個應用創建一個Consumer,由應用來維護此對象,可以設置為全局對象或者單例
         * 注意:ConsumerGroupName需要由應用來保證唯一
         */
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(producerGroup);
        // consumer.setNamesrvAddr("10.10.0.102:9876");
        consumer.setNamesrvAddr(namesrvAddr);
        /**
         * 訂閱指定topic下tags分別等于TagA或TagC或TagD
         */
        consumer.subscribe("Topic1", "TagA || TagC || TagD");
        /**
         * 訂閱指定topic下所有消息<br>
         * 注意:一個consumer對象可以訂閱多個topic
         */
        consumer.subscribe("Topic2", "*");
        consumer.subscribe("Topic3", "*");


        /**
         * 設置Consumer第一次啟動是從隊列頭部開始消費還是隊列尾部開始消費 如果非第一次啟動,那么按照上次消費的位置繼續消費
         */
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            /**
             * 默認msgs里只有一條消息,可以通過設置consumeMessageBatchMaxSize參數來批量接收消息
             */
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(
                    List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                System.out.println(Thread.currentThread().getName() + " Receive New Messages: " + msgs);

                MessageExt msg = msgs.get(0);
                if (msg.getTopic().equals("Topic1")) {
                    if (null != msg.getTags()) {
                        // 執行Topic1的消費邏輯
                        if (msg.getTags().equals("TagA")) {
                            // 執行TagA的消費
                            System.out.println("TagA開始。");
                        } else if (msg.getTags().equals("TagC")) {
                            System.out.println("TagC開始。");
                            // 執行TagC的消費
                        } else if (msg.getTags().equals("TagD")) {
                            // 執行TagD的消費
                            System.out.println("TagD開始。");
                        }
                    }
                } else if (msg.getTopic().equals("Topic2")) {
                    // 執行Topic2的消費邏輯
                    System.out.println("Topic2");
                }
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        /**
         * Consumer對象在使用之前必須要調用start初始化,初始化一次即可
         */
        consumer.start();
        System.out.println("Consumer Started.");
    }

}

3.3 properties配置文件


# 消費者的組名
apache.rocketmq.consumer.PushConsumer=PushConsumer
# 生產者的組名
apache.rocketmq.producer.producerGroup=Producer
# NameServer地址
apache.rocketmq.namesrvAddr=192.168.220.72:9876
# 設置應用端口
server.port=8089

3.4 測試代碼


/**
 * @author Coder編程
 * @Title: HelloWord
 * @ProjectName rocketmq
 * @Description: Hello World
 * @date 2019/5/814:14
 */

@RestController
public class Test {

    @Autowired
    private Producer producer;

    @Autowired
    private Consumer consumer;

    @RequestMapping("/test")
    public String testMQ2() {
        try {
            System.out.println("-----------------開始生產-----------------");
            producer.orderedProducer();
            System.out.println("-----------------開始消費-----------------");
            consumer.orderedConsumer();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "success";
    }

}


4.奉上源碼

以上安裝jar包和案例測試源碼已經上傳至GitHub/Gitee

源碼圖

源碼地址:

Github地址

Gitee地址

文末

歡迎關注公眾號:Coder編程
獲取最新原創技術文章和相關免費學習資料,隨時隨地學習技術知識!

微信公眾號

求關注
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容