首页 > 技术文章 > 阿里RocketMq试用记录+简单的Spring集成

jobs-lgy 2017-01-19 17:35 原文

<h1>
    <span class="link_title"><a href="/jeffwxz/article/details/49633383">
    阿里RocketMq试用记录+简单的Spring集成            
    </a></span>
</h1>
    <div class="article_manage clearfix">
    <div class="article_l">
        <span class="link_categories">
        标签:
          <a href="http://www.csdn.net/tag/spring" target="_blank" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">spring</a><a href="http://www.csdn.net/tag/RocketMq" target="_blank" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">RocketMq</a>
        </span>
    </div>
    <div class="article_r">
        <span class="link_postdate">2015-11-04 09:34</span>
        <span class="link_view" title="阅读次数">5029人阅读</span>
        <span class="link_comments" title="评论次数"> <a href="#comments" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_pinglun'])">评论</a>(0)</span>
        <span class="link_collect tracking-ad" data-mod="popu_171"> <a href="javascript:void(0);" onclick="javascript:collectArticle('%e9%98%bf%e9%87%8cRocketMq%e8%af%95%e7%94%a8%e8%ae%b0%e5%bd%95%2b%e7%ae%80%e5%8d%95%e7%9a%84Spring%e9%9b%86%e6%88%90','49633383');return false;" title="收藏">收藏</a></span>
         <span class="link_report"> <a href="#report" onclick="javascript:report(49633383,2);return false;" title="举报">举报</a></span>

    </div>
</div>
<div class="embody" style="display:none" id="embody">
    <span class="embody_t">本文章已收录于:</span>
    <div class="embody_c" id="lib" value="{&quot;err&quot;:0,&quot;msg&quot;:&quot;ok&quot;,&quot;data&quot;:[]}"></div>
</div>
<style type="text/css">        
        .embody{
            padding:10px 10px 10px;
            margin:0 -20px;
            border-bottom:solid 1px #ededed;                
        }
        .embody_b{
            margin:0 ;
            padding:10px 0;
        }
        .embody .embody_t,.embody .embody_c{
            display: inline-block;
            margin-right:10px;
        }
        .embody_t{
            font-size: 12px;
            color:#999;
        }
        .embody_c{
            font-size: 12px;
        }
        .embody_c img,.embody_c em{
            display: inline-block;
            vertical-align: middle;               
        }
         .embody_c img{               
            width:30px;
            height:30px;
        }
        .embody_c em{
            margin: 0 20px 0 10px;
            color:#333;
            font-style: normal;
        }
</style>
<script type="text/javascript">
    $(function () {
        try
        {
            var lib = eval("("+$("#lib").attr("value")+")");
            var html = "";
            if (lib.err == 0) {
                $.each(lib.data, function (i) {
                    var obj = lib.data[i];
                    //html += '<img src="' + obj.logo + '"/>' + obj.name + "&nbsp;&nbsp;";
                    html += ' <a href="' + obj.url + '" target="_blank">';
                    html += ' <img src="' + obj.logo + '">';
                    html += ' <em><b>' + obj.name + '</b></em>';
                    html += ' </a>';
                });
                if (html != "") {
                    setTimeout(function () {
                        $("#lib").html(html);                      
                        $("#embody").show();
                    }, 100);
                }
            }      
        } catch (err)
        { }
        
    });
</script>
  <div class="category clearfix">
    <div class="category_l">
       <img src="http://static.blog.csdn.net/images/category_icon.jpg">
        <span>分类:</span>
    </div>
    <div class="category_r">
                <label>
                    <span onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_fenlei']);">中间件<em></em></span>                       
                </label>      
    </div>
</div>
<script type="text/javascript" src="http://static.blog.csdn.net/scripts/category.js"></script>  
    <div class="bog_copyright">         
        <p class="copyright_p">版权声明:本文为博主原创文章,未经博主允许不得转载。</p>
    </div>

RocketMq试用+简单的Spring集成

经过2天的试用初步了解了一下RocketMq的基本用法,搜索了一下度娘,没有找到spring的例子,所以简单搞了一点代码感受一下。

1.RocketMq

RocketMQ的前身是Metaq,当Metaq3.0发布时,产品名称改为RocketMQ,有以下特点:
1) 能够保证严格的消息顺序
2) 提供丰富的消息拉取模式
3) 高效的订阅者水平扩展能力
4)实时的消息订阅机制
5)亿级消息堆积能力

2.核心原理

2.1. 数据结构

RocketMq
这里写图片描述

(1)所有数据单独储存到commit Log ,完全顺序写,随机读
(2)对最终用户展现的队列实际只储存消息在Commit Log 的位置信息,并且串行方式刷盘
(3)按照MessageId查询消息
这里写图片描述
(4)根据查询的key的hashcode%slotNum得到具体的槽位置
这里写图片描述
(5)根据slotValue(slot对应位置的值)查找到索引项列表的最后一项
(6)遍历索引项列表返回查询时间范围内的结果集

2.2. 刷盘策略

rocketmq中的所有消息都是持久化的,先写入系统pagecache,然后刷盘,可以保证内存与磁盘都有一份数据,访问时,可以直接从内存读取

使用简单的符号标识不同的标题,将某些文字标记为粗体或者斜体,创建一个链接等,详细语法参考帮助?。

本编辑器支持 Markdown Extra ,  扩展了很多好用的功能。具体请参考[Github][2].

2.3. 内存机制

这里写图片描述

2.4. 工作模式

这里写图片描述

3. 环境安装

3.1. JAVA环境安装

安装

rpm -ivh jdk-7u80-linux-x64.rpm
  • 1
  • 1

环境变量

JAVA_HOME=/usr/java/jdk1.7.0_80
CLASSPATH=.:$JAVA_HOME/lib.tools.jar
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME CLASSPATH PATH
export ROCKETMQ_HOME=/usr/local/service/alibaba-rocketmq
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

3.2. RocketMq安装

https://github.com/alibaba/RocketMQ/releases下载3.2.6,解压

4. 测试网络拓扑

这里写图片描述

因为手里没有其他服务器,105那台缺少一个slave,在同步双写模式下,发送消息会返回 SLAVE_NOT_AVAILABLE,不过消息已经发送成功,只是slave没有写成功。

5. 启停操作

这里只给出一个基本的示例,各个模式的启停在本文最后的参考文献中会有详细的说明。这里不再赘述。
  • 启动nameserver
nohup ./mqnamesrv &
  • 1
  • 1
  • 停止nameServer
./mqshutdown namesrv
  • 1
  • 1
  • 启动broker(单master)(多master,多master+slave)对应的(异步复制,同步双写)
nohup sh mqbroker -n 192.168.146.109:9876 -c $ROCKETMQ_HOME/conf/2m-noslave/broker-a.properties &
  • 1
  • 1
  • 停止broker
./mqshutdown broker
  • 1
  • 1

6. 运维指令

  • 查看集群情况
./mqadmin clusterList -n 127.0.0.1:9876
  • 1
  • 1
  • 查看broker状态
./mqadmin brokerStatus -n 127.0.0.1:9876 -b 192.168.146.105:10911
  • 1
  • 1
  • 查看topic列表
./mqadmin topicList -n 127.0.0.1:9876
  • 1
  • 1
  • 查看topic状态
./mqadmin topicStatus -n 127.0.0.1:9876 -t PushTopic
  • 1
  • 1
  • 查看topic路由
./mqadmin topicRoute  -n 127.0.0.1:9876 -t PushTopic
  • 1
  • 1

7. 基本测试

基本测试采用Java直接编码的方式生产和消费消息,例子来源于参考文献的《RocketMQ开发教程》。本文最后的代码示例,采用了spring的形式。

  • Producer
package com.jd.wxz;

import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.alibaba.rocketmq.client.producer.SendResult;
import com.alibaba.rocketmq.common.message.Message;

public class Producer {
    public static void main(String[] args){
        DefaultMQProducer producer = new DefaultMQProducer("Producer");
        producer.setNamesrvAddr("192.168.146.109:9876"); 
        try {
            producer.start();

            Message msg = new Message("PushTopic", 
                    "push", 
                    "1", 
                    "Just for test.".getBytes());

            SendResult result = producer.send(msg);
            System.out.println("id:" + result.getMsgId() +
                    " result:" + result.getSendStatus());

            msg = new Message("PushTopic", 
                    "push", 
                    "2", 
                    "Just for test.".getBytes());

            result = producer.send(msg);
            System.out.println("id:" + result.getMsgId() +
                    " result:" + result.getSendStatus());

            msg = new Message("PullTopic", 
                    "pull", 
                    "1", 
                    "Just for test.".getBytes());

            result = producer.send(msg);
            System.out.println("id:" + result.getMsgId() +
                    " result:" + result.getSendStatus());
        } catch (Exception e) {
            e.printStackTrace();
        }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
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 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
  • 43
  • 44
  • 45
  • 46
  • Consumer

package com.sean;

import java.util.List;

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.common.consumer.ConsumeFromWhere;
import com.alibaba.rocketmq.common.message.Message;
import com.alibaba.rocketmq.common.message.MessageExt;

public class Consumer {
    public static void main(String[] args){
        DefaultMQPushConsumer consumer = 
                new DefaultMQPushConsumer("PushConsumer");
        consumer.setNamesrvAddr("192.168.146.109:9876"); 
        try {
            //订阅PushTopic下Tag为push的消息
            consumer.subscribe("PushTopic", "push");
            //程序第一次启动从消息队列头取数据
            consumer.setConsumeFromWhere(
                    ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
            consumer.registerMessageListener(
                new MessageListenerConcurrently() {
                    public ConsumeConcurrentlyStatus consumeMessage(
                            List<MessageExt> list,
                            ConsumeConcurrentlyContext Context) {
                        Message msg = list.get(0);
                        System.out.println(msg.toString());
                        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
                    }
                }
            );
            consumer.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 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
  • 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

运行结果:
这里写图片描述
这里写图片描述

服务端监控:
这里写图片描述

8.宕机实验

这里写图片描述

9.遗留问题

1)  关闭master 自动切换到slave无法实现,官方资料上没有明确指明,第三方文档里有(见文献3)。
2)  在开发机服务器上运行os.sh进行优化,导致网络无法连接,运维帮忙重启才恢复。

10.RocketMq+Spring源码下载

戳我

11.参考文献

1) 《RocketMq入门(上)》

2) 《RocketMq入门(下)》

3) 《Rokectmq开发教程》

4) 《阿里Rocketmq Quict Start》

5) 《RocketMQ与Kafka对比(18项差异)》

6) 《RocketMq命令整理》

7) 《RocketMq原理简介》

    <div id="digg" articleid="49633383">
        <dl id="btnDigg" class="digg digg_enable" onclick="btndigga();">
           
             <dt>顶</dt>
            <dd>0</dd>
        </dl>
       
          
        <dl id="btnBury" class="digg digg_enable" onclick="btnburya();">
          
              <dt>踩</dt>
            <dd>0</dd>               
        </dl>
        
    </div>
 <div class="tracking-ad" data-mod="popu_222"><a href="javascript:void(0);">&nbsp;</a>   </div>
<div class="tracking-ad" data-mod="popu_223"> <a href="javascript:void(0);">&nbsp;</a></div>
<script type="text/javascript">
            function btndigga() {
                $(".tracking-ad[data-mod='popu_222'] a").click();
            }
            function btnburya() {
                $(".tracking-ad[data-mod='popu_223'] a").click();
            }
        </script>
<div style="clear:both; height:10px;"></div>


    <div class="similar_article" style="display:none">
            <h4>我的同类文章</h4>
            <div class="similar_c" style="margin:20px 0px 0px 0px">
                <div class="similar_c_t">
                </div>
               
                <div class="similar_wrap tracking-ad" data-mod="popu_141" style="max-height:195px;">
                    <a href="http://blog.csdn.net" style="display:none">http://blog.csdn.net</a>
                    <ul class="similar_list fl"></ul>

                    <ul class="similar_list fr"></ul>
                </div>
            </div>
        </div>    
<script type="text/javascript">
    $(function () {
        GetCategoryArticles('0', 'jeffwxz','foot','49633383');
    });
</script>
 <div>
         <ins data-revive-zoneid="206" data-revive-id="8c38e720de1c90a6f6ff52f3f89c4d57"></ins> 
</div>

参考知识库

img

Linux知识库

img

Java SE知识库

img

Java EE知识库

img

Java 知识库

img

软件测试知识库

img

算法与数据结构知识库

 <dt><span>猜你在找</span></dt>    





<div id="adCollege" style="width: 42%;float: left;"> 
    <script src="http://csdnimg.cn/jobreco/job_reco.js" type="text/javascript"></script> 
    <script type="text/javascript">
        csdn.position.showEdu({
            sourceType: "blog",
            searchType: "detail",
            searchKey: "49633383",
            username: "liuguoyun_123456",
            recordcount: "5",
            containerId: "adCollege" //容器DIV的id。 
        });
    </script> 
<div class="tracking-ad" data-mod="popu_84"><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px; white-space: nowrap;"><a href="http://edu.csdn.net/course/detail/3241" title="大数据平台hadoop运维之hadoop快速入门" strategy="v4:content" target="_blank">大数据平台hadoop运维之hadoop快速入门</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px; white-space: nowrap;"><a href="http://edu.csdn.net/course/detail/2788" title="spring3.2入门到大神(备java基础、jsp、servlet,javaee精髓)" strategy="v4:content" target="_blank">spring3.2入门到大神(备java基础、jsp、servlet,javaee精髓)</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px; white-space: nowrap;"><a href="http://edu.csdn.net/course/detail/2351" title="途牛冯学奎:复杂环境以及高速业务发展下途牛度假订单的建设与运维" strategy="v4:content" target="_blank">途牛冯学奎:复杂环境以及高速业务发展下途牛度假订单的建设与运维</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px; white-space: nowrap;"><a href="http://edu.csdn.net/course/detail/3837" title="WEB安全攻防技术精讲视频教程(全漏洞原理+攻击手段+测试方法+预防措施)" strategy="v4:content" target="_blank">WEB安全攻防技术精讲视频教程(全漏洞原理+攻击手段+测试方法+预防措施)</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px; white-space: nowrap;"><a href="http://edu.csdn.net/course/detail/3478" title="如何使用Spring XD构建Data Microservices" strategy="v4:content" target="_blank">如何使用Spring XD构建Data Microservices</a></dd></div></div>  


 <div id="res" data-mod="popu_36" class="tracking-ad" style="width: 42%; float: left; margin-right: 30px; display: block;"><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="http://blog.csdn.net/sadfishsc/article/details/50808027" title="Spring集成Quartz的简单配置" strategy="SearchAlgorithm">Spring集成Quartz的简单配置</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="http://blog.csdn.net/runming56/article/details/34107797" title="Activiti环境配置项目搭建与Spring集成简单示例" strategy="SearchAlgorithm">Activiti环境配置项目搭建与Spring集成简单示例</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="http://blog.csdn.net/u013803262/article/details/44538545" title="简单明了地解释JMS  相关概念 以及JMS的实例代码下载 传统使用方式非Spring框架下的集成" strategy="SearchAlgorithm">简单明了地解释JMS  相关概念 以及JMS的实例代码下载 传统使用方式非Spring框架下的集成</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="http://blog.csdn.net/gavin5033/article/details/51455846" title="SpringMVC+Spring4+Mybatis3集成开发简单Web项目+源码下载" strategy="SearchAlgorithm">SpringMVC+Spring4+Mybatis3集成开发简单Web项目+源码下载</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="http://blog.csdn.net/konglongaa/article/details/51706991" title="持久化框架SpringMVC+Spring4+Mybatis3 集成开发简单Web项目+源码下载" strategy="SearchAlgorithm">持久化框架SpringMVC+Spring4+Mybatis3 集成开发简单Web项目+源码下载</a></dd></div>
<div id="ad_cen">        
                  <ins data-revive-zoneid="199" data-revive-id="8c38e720de1c90a6f6ff52f3f89c4d57"></ins>
</div>  

<!-- 广告位开始 -->
<ins data-revive-zoneid="72" data-revive-id="8c38e720de1c90a6f6ff52f3f89c4d57"></ins>
<!-- 广告位结束 -->
查看评论

  暂无评论

发表评论
  • 用 户 名:
  • liuguoyun_123456
      
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
<div id="ad_bot">
</div>
    <a id="quick-reply" class="btn btn-top q-reply" title="快速回复" style="display:none;">
        <img src="http://static.blog.csdn.net/images/blog-icon-reply.png" alt="快速回复">
    </a>    
<a id="d-top-a" class="btn btn-top backtop" style="display: none;" title="返回顶部" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_huidaodingbu'])">         
     <img src="http://static.blog.csdn.net/images/top.png" alt="TOP">
</a>

                    <div class="clear">
                    </div>
                </div>

推荐阅读