阿里RocketMq试用记录+简单的Spring集成
<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="{"err":0,"msg":"ok","data":[]}"></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 + " ";
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. 数据结构
(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.参考文献
<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);"> </a> </div>
<div class="tracking-ad" data-mod="popu_223"> <a href="javascript:void(0);"> </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>
<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>
<!-- 广告位结束 -->
<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>
<h5>
<a href="http://www.csdn.net/tag/" target="_blank">核心技术类目</a></h5>
<div class="classify">
全部主题
Hadoop
AWS
移动游戏
Java
Android
iOS
Swift
智能硬件
Docker
OpenStack
VPN
Spark
ERP
IE10
Eclipse
CRM
JavaScript
数据库
Ubuntu
NFC
WAP
jQuery
BI
HTML5
Spring
Apache
.NET
API
HTML
SDK
IIS
Fedora
XML
LBS
Unity
Splashtop
UML
components
Windows Mobile
Rails
QEMU
KDE
Cassandra
CloudStack
FTC
coremail
OPhone
CouchBase
云计算
iOS6
Rackspace
Web App
SpringSide
Maemo
Compuware
大数据
aptech
Perl
Tornado
Ruby
Hibernate
ThinkPHP
HBase
Pure
Solr
Angular
Cloud Foundry
Redis
Scala
Django
Bootstrap
<div class="clear">
</div>
</div>
暂无评论