消费者角色:

1. 推式(一般建议用推式)

2. 拉式

消费模式:

1. 集群(cluster)                --均衡负载消费

2. 广播(broadcasting) --发布和订阅者模式

MQ的消费不会清除broker中的数据,broker数据一直存在队列中,队列offset会一直递增,因此可以通过回查来获取到丢失数据。这个时候我们可以采用pull形式较好。

push形式,MQ会记录访问的偏移量,即使宕机下次重启也会按照顺序继续消费,不会出现重复消费。

RocketMQ入门(生产者)_2中已经写过一个推式的代码,接下来就看下拉式。

/**
* 普通拉式消费者,代码编写
* @author DennyZhao
*
*/
public class PullConsumer { /**
* 暂时以map作为offset入库看待。<queueId, offset>
*/
private static Map<String, Long> offsetMap = new HashMap<String, Long>(); public static void main(String[] args) throws UnsupportedEncodingException {
//创建拉式消费者
DefaultMQPullConsumer pullConsumer = new DefaultMQPullConsumer("pullConsumerGroup");
pullConsumer.setNamesrvAddr("192.168.68.137:9876;192.168.68.138:9876;");
try {
pullConsumer.start();
Set<MessageQueue> mqSet= pullConsumer.fetchSubscribeMessageQueues("fruit");
while(true) {
//循环队列
for(MessageQueue mq: mqSet) {
// 从队列中获取固定偏移值
PullResult pullResult = pullConsumer.pullBlockIfNotFound(mq, "*", getOffset(mq), 32);
setOffset(mq, pullResult.getNextBeginOffset());
switch(pullResult.getPullStatus()) {
case FOUND:
List<MessageExt> msgFoundList = pullResult.getMsgFoundList();
for(MessageExt msg : msgFoundList) {
String fruit = new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET);
System.out.println(fruit + " -----fruit");
}
break;
case NO_NEW_MSG:
break;
case NO_MATCHED_MSG:
break;
}
}
Thread.sleep(2000);
}
} catch (MQClientException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemotingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MQBrokerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} /**
* set offset
* @param mq
* @param nextBeginOffset
*/
private static void setOffset(MessageQueue mq, long nextBeginOffset) {
String queueId = mq.getBrokerName() + mq.getTopic() + mq.getQueueId();
offsetMap.put(queueId, nextBeginOffset);
} /**
* 获取固定偏移值
* @param mq queueId
* @return int
*/
private static long getOffset(MessageQueue mq) {
String queueId = mq.getBrokerName() + mq.getTopic() + mq.getQueueId();
Long offset = offsetMap.get(queueId);
if(offset == null) {
offset = 0l;
}
System.out.println(offset + "---------------");
return offset;
} }

使用Schedule拉式:

/**
* ScheduleService 進行數據拉取
* @author DennyZhao
*
*/
public class PullScheduleService { public static void main(String[] args) throws MQClientException {
MQPullConsumerScheduleService scheduleService = new MQPullConsumerScheduleService("scheduleConsumers");
scheduleService.setMessageModel(MessageModel.CLUSTERING);
scheduleService.setPullThreadNums(4);
DefaultMQPullConsumer defaultMQPullConsumer = new DefaultMQPullConsumer("pullConsumer");
defaultMQPullConsumer.setNamesrvAddr("192.168.68.137:9876;192.168.68.138:9876;");
scheduleService.setDefaultMQPullConsumer(defaultMQPullConsumer);
scheduleService.registerPullTaskCallback("fruit", new PullTaskCallback() {
/**
* 数据处理
*/
@Override
public void doPullTask(MessageQueue mq, PullTaskContext context) {
MQPullConsumer pullConsumer = context.getPullConsumer();
try {
long offset = pullConsumer.fetchConsumeOffset(mq, false);
PullResult pull = pullConsumer.pull(mq, "*", offset, 32);
switch(pull.getPullStatus()) {
case FOUND:
// 结果输出
List<MessageExt> msgFoundList = pull.getMsgFoundList();
for(MessageExt msg : msgFoundList) {
String fruit = new String(msg.getBody(), RemotingHelper.DEFAULT_CHARSET);
System.out.println("result: " + fruit);
}
break;
case NO_MATCHED_MSG:
break;
default: }
// 获取下一个循环的offset
pullConsumer.updateConsumeOffset(mq, pull.getNextBeginOffset());
// 设置下次访问时间
context.setPullNextDelayTimeMillis(1000);
} catch (MQClientException | RemotingException | MQBrokerException | InterruptedException | UnsupportedEncodingException e) {
e.printStackTrace();
}
}
});
scheduleService.start();
} }

参数说明:

//push主要参数
DefaultMQPushConsumer pushConsumer = new DefaultMQPushConsumer("pushConsumerGroup");
// 从何地开始,默认(CONSUME_FROM_LAST_OFFSET)
pushConsumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
pushConsumer.setConsumeThreadMin(2); //最小线程数
pushConsumer.setConsumeThreadMax(8); //最大线程数
pushConsumer.setConsumeTimeout(5000); //连接超时
pushConsumer.setMessageModel(MessageModel.CLUSTERING);//消息模式(集群CLUSTERING和广播BROADCASTING,default:cluster)
pushConsumer.setConsumeConcurrentlyMaxSpan(1000);//单队列最大消费数1000
pushConsumer.setConsumeMessageBatchMaxSize(1); //批量消费数1
pushConsumer.setNamesrvAddr("192.168.68.137:9876;192.168.68.138:9876;");//集群IP
pushConsumer.setHeartbeatBrokerInterval(2000); //心跳监测
pushConsumer.setMaxReconsumeTimes(3);//重复消费次数,用于失败后重试
pushConsumer.queryMessage(topic, key, maxNum, begin, end); //获取消息
pushConsumer.fetchSubscribeMessageQueues(topic);//订阅topic
pushConsumer.registerMessageListener(new MessageListenerConcurrently());//及时普通消费型
pushConsumer.registerMessageListener(new MessageListenerOrderly()); //严格顺序消费型;
        // pull常用参数
//消息模式(集群CLUSTERING和广播BROADCASTING,default:cluster)
pullConsumer.setMessageModel(MessageModel.CLUSTERING);
pullConsumer.fetchSubscribeMessageQueues(topic); //订阅主题
pullConsumer.fetchConsumeOffset(mq, false); //获取queue当前offset位置
pullConsumer.pullBlockIfNotFound(mq, subExpression, offset, maxNums);//获取消费内容
pullConsumer.updateConsumeOffset(mq, offset); //更新消费位置
pullConsumer.setConsumerPullTimeoutMillis(5000); //连接超时

RocketMQ入门(消费者)_3的更多相关文章

  1. RocketMQ入门(2)最佳实践

    转自:http://www.changeself.net/archives/rocketmq入门(2)最佳实践.html RocketMQ入门(2)最佳实践 一.服务端安装部署 我是在虚拟机中的Cen ...

  2. 必须先理解的RocketMQ入门手册,才能再次深入解读

    RocketMQ入门手册 RocketMQ是一个分布式.队列模型的开源消息中间件,前身是MetaQ,是阿里研发的一个队列模型的消息中间件,后开源给apache基金会成为了apache的顶级开源项目,具 ...

  3. RocketMQ入门到入土(二)事务消息&顺序消息

    接上一篇:RocketMQ入门到入土(一)新手也能看懂的原理和实战! 一.事务消息的由来 1.案例 引用官方的购物案例: 小明购买一个100元的东西,账户扣款100元的同时需要保证在下游的积分系统给小 ...

  4. RocketMQ入门(3)拉取消息

    转自:http://www.changeself.net/archives/rocketmq入门(3)拉取消息.html RocketMQ入门(3)拉取消息 RocketMQ不止可以直接推送消息,在消 ...

  5. RocketMQ入门(1)

    转自:http://www.changeself.net/archives/rocketmq入门(1).html RocketMQ入门(1) RocketMQ是一款分布式.队列模型的消息中间件,具有以 ...

  6. RocketMQ之消费者启动与消费流程

    vivo 互联网服务器团队 - Li Kui 一.简介 1.1 RocketMQ 简介 RocketMQ是由阿里巴巴开源的分布式消息中间件,支持顺序消息.定时消息.自定义过滤器.负载均衡.pull/p ...

  7. 消息队列之-RocketMQ入门

    简介 RocketMQ是阿里开源的消息中间件,目前已经捐献个Apache基金会,它是由Java语言开发的,具备高吞吐量.高可用性.适合大规模分布式系统应用等特点,经历过双11的洗礼,实力不容小觑. 官 ...

  8. 轻松搞定RocketMQ入门

    RocketMQ是一款分布式.队列模型的消息中间件,具有以下特点: 能够保证严格的消息顺序 提供丰富的消息拉取模式 高效的订阅者水平扩展能力 实时的消息订阅机制 亿级消息堆积能力 RocketMQ网络 ...

  9. RocketMQ入门(生产者)_2

    从 RocketMQ环境搭建_1 我们已经建立了MQ的Server,接下来就是简单的生产和消费的过程. 1. rocketMQ的源码中有个示例代码example  ,我们从Apache官网中可以下载源 ...

随机推荐

  1. 2018-2019-2 网络对抗技术 20165308 Exp2 后门原理与实践

    2018-2019-2 网络对抗技术 20165308 Exp2 后门原理与实践 1.实验内容 (3.5分) (1)使用netcat获取主机操作Shell,cron启动 (0.5分) (2)使用soc ...

  2. [转]Linux中python3.6+ipython+Jupyter Notebook环境

    python3.6安装 下载python安装包,这里下载的最新的3.6.1版本 https://www.python.org/ftp/python/3.6.1/ 将安装包上传到服务器并解压 tar z ...

  3. Redis 5.0.3集群部署

    参考文章 https://blog.csdn.net/yyTomson/article/details/85783753 https://www.cnblogs.com/zy-303/p/102731 ...

  4. Linux shell 重定向学习笔记

    在了解重定向之前,我们先来看看linux 的文件描述符. linux文件描述符:可以理解为linux跟踪打开文件,而分配的一个数字,这个数字有点类似c语言操作文件时候的句柄,通过句柄就可以实现文件的读 ...

  5. vue实现原理

    1.数据监控(data):监听data属性: new Vue之后内部扫描data属性值,用 Object.defineProperty(obj,name,{ set:value=>{ obj[_ ...

  6. puzz: 图片和表单上传的不一致问题

    1.    方向1 用户提交表单, 图片和表单同步上传.(由同一服务器处理, 服务器压力大. 没有分离) 2.    方向2 图片和表单分开上传. 如图片访问ftp,表单提交后台(图片和后台分离) 2 ...

  7. 通过 Git 上传代码到 GitHub 必要操作详解

    目录 Git 介绍 起步 下载 配置 准备 在 GitHub 上创建 SSH Key 提交 修改代码 更多信息 Git 欢迎来到 Git 的学习. 介绍 首先先了解一下 Git. Git,是一个开源的 ...

  8. BAT开发中,ChromeDriver版本兼容性检查

    打开解决方案的Nuget包管理器,选择合适的版本,安装即可.版本的兼容性检查,见上一篇blog(初次使用BAT,请检查Chrome浏览器和ChromeDriver兼容性 https://www.cnb ...

  9. 反射 内省 BeanUtil 综合使用

    package com.zsphp.domain; public class User { private String userId; private String userName; privat ...

  10. 生信基础知识【04】GO和pathway分析

    非原创 参考资料: 一文掌握GO和pathway分析 - 生物信息学讨论版 -丁香园论坛http://www.dxy.cn/bbs/thread/34904124#34904124 GO富集 GO是G ...