rocketmq消息重复推送的问题
最近,在公司的测试环境,遇到个问题,每次重启应用重启后,原来消费过的消息又被重复推送了一遍,消费者和生产者代码如下:
package com.tf56.queue.client; import java.util.concurrent.TimeUnit; import com.alibaba.rocketmq.client.exception.MQBrokerException;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.alibaba.rocketmq.client.producer.SendResult;
import com.alibaba.rocketmq.common.message.Message;
import com.alibaba.rocketmq.remoting.exception.RemotingException;
/**
* RocketMQ 生产者工具类
* @author zjhua
*
*/
public class RocketMQProducer { private DefaultMQProducer producer;
private String namesrvAddr;
private String groupName;
private String instanceName; public String getNamesrvAddr() {
return namesrvAddr;
} public void setNamesrvAddr(String namesrvAddr) {
this.namesrvAddr = namesrvAddr;
} public String getGroupName() {
return groupName;
} public void setGroupName(String groupName) {
this.groupName = groupName;
} public String getInstanceName() {
return instanceName;
} public void setInstanceName(String instanceName) {
this.instanceName = instanceName;
} public RocketMQProducer(String namesrvAddr, String groupName,
String instanceName) {
super();
this.namesrvAddr = namesrvAddr;
this.groupName = groupName;
this.instanceName = instanceName;
this.producer = new DefaultMQProducer(groupName); producer.setNamesrvAddr(namesrvAddr);
producer.setInstanceName(instanceName);
producer.setVipChannelEnabled(false); try {
producer.start();
} catch (MQClientException e) {
e.printStackTrace();
}
} /**
* 发送消息工具类
* @param topic
* @param tags
* @param keys
* @param body
* @return
* @throws MQClientException
* @throws RemotingException
* @throws MQBrokerException
* @throws InterruptedException
*/
public SendResult send(String topic, String tags, String keys, byte[] body)
throws MQClientException, RemotingException, MQBrokerException,
InterruptedException {
Message msg = new Message(topic, tags, keys, body);
try {
SendResult sendResult = this.producer.send(msg);
return sendResult;
} catch (MQClientException | RemotingException | MQBrokerException
| InterruptedException e) {
e.printStackTrace();
throw e;
}
} /**
* 发送工具类
* @param topic
* @param tags
* @param keys
* @param body
* @param retryTimes
* @param elapseMS
* @return
*/
public SendResult send(String topic, String tags, String keys, byte[] body,int retryTimes,int elapseMS) {
Message msg = new Message(topic, tags, keys, body);
boolean success = false;
int i = 0;
SendResult sendResult = null;
while (!success && i++ < retryTimes) {
try {
sendResult = this.producer.send(msg);
return sendResult;
} catch (MQClientException | RemotingException | MQBrokerException
| InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(elapseMS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return sendResult;
} public static void main(String[] args) throws MQClientException,
InterruptedException {
RocketMQProducer producer = new RocketMQProducer("10.7.29.121:9876",
"ProducerGroupName", "Producer"); for (int i = 0; i < 10; i++) {
try {
{
SendResult sendResult = producer.send("TopicTestZJH",// topic
"TagA",// tag
"OrderID001",// key
("Hello MetaQ" + i).getBytes());
System.out.println(sendResult);
} {
SendResult sendResult = producer.send("TopicTestYIDU",// topic
"TagB",// tag
"OrderID0034",// key
("Hello MetaQ" + i).getBytes());
System.out.println(sendResult);
}
} catch (Exception e) {
e.printStackTrace();
}
TimeUnit.MILLISECONDS.sleep(1000);
}
/**
* spring bean配置
*/
// <bean id="rocketMQProducer" class="com.tf56.queue.client.RocketMQProducer">
// <constructor-arg name="namesvrAddr" value="10.7.29.121:9876"/>
// <constructor-arg name="groupName" value="ProducerGroupName"/>
// <constructor-arg name="instanceName" value="Producer"/>
// </bean>
}
}
消费端代码:
package tf56.sofa.util; import java.net.InetAddress;
import java.net.UnknownHostException;
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.client.exception.MQClientException;
import com.alibaba.rocketmq.common.consumer.ConsumeFromWhere;
import com.alibaba.rocketmq.common.message.MessageExt;
import com.alibaba.rocketmq.common.protocol.heartbeat.MessageModel; public class RocketMQPushConsumer { private DefaultMQPushConsumer consumer;
private String namesrvAddr;
private String groupName;
private String instanceName;
private String topics; public RocketMQPushConsumer(String namesrvAddr, String groupName, String instanceName,String topics,MessageListenerConcurrently messageListener) {
super();
this.namesrvAddr = namesrvAddr;
this.groupName = groupName;
this.instanceName = instanceName;
this.topics = topics; /**
* 一个应用创建一个Consumer,由应用来维护此对象,可以设置为全局对象或者单例<br>
* 注意:ConsumerGroupName需要由应用来保证唯一
*/
consumer = new DefaultMQPushConsumer(groupName);
consumer.setNamesrvAddr(namesrvAddr);
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
consumer.setInstanceName(RocketMQPushConsumer.getInstanceName(namesrvAddr));
consumer.setMessageModel(MessageModel.CLUSTERING);
consumer.setVipChannelEnabled(false);
try {
/**
* 订阅指定topic下所有消息<br>
* 注意:一个consumer对象可以订阅多个topic
*/ String[] topicsArr = topics.split(";");
for(int i=0;i<topicsArr.length;i++) {
consumer.subscribe(topicsArr[i], "*");
} consumer.registerMessageListener(messageListener);
} catch (Exception e) {
e.printStackTrace();
return;
}
System.out.println("Consumer Started.");
} /**
* Consumer对象在使用之前必须要调用start初始化,初始化一次即可<br>
*/
public void init() {
try {
consumer.start();
} catch (MQClientException e) {
e.printStackTrace();
}
} private static String getInstanceName(String namesrvAddr) {
return getHostAddress() + namesrvAddr;
} private static String getHostAddress(){
try {
return InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
return "";
} /**
* 当前例子是PushConsumer用法,使用方式给用户感觉是消息从RocketMQ服务器推到了应用客户端。<br>
* 但是实际PushConsumer内部是使用长轮询Pull方式从MetaQ服务器拉消息,然后再回调用户Listener方法<br>
*/
public static void main(String[] args) throws InterruptedException,
MQClientException {
MessageListenerConcurrently messageListener = new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(
List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
MessageExt msg = msgs.get(0);
if (msg.getTopic().equals("TopicTestZJH")) {
System.out.println("TopicTestZJH->" + new String(msg.getBody()));
} else if (msg.getTopic().equals("TopicTestYIDU")) {
System.out.println("TopicTestYIDU->" + new String(msg.getBody()));
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
};
RocketMQPushConsumer consumer = new RocketMQPushConsumer("10.7.29.121:9876",
"ConsumerGroupName", "Consumer","TopicTestZJH;TopicTestYIDU",messageListener);
consumer.init();
/**
* spring构造器注入
*/
// <bean id="rocketMQPushConsumer" class="com.tf56.queue.client.RocketMQPushConsumer">
// <constructor-arg name="namesvrAddr" value="10.7.29.121:9876"/>
// <constructor-arg name="groupName" value="ConsumerGroupName"/>
// <constructor-arg name="instanceName" value="Consumer"/>
// <constructor-arg name="topics" value="TopicTestZJH;TopicTestYIDU"/>
// <constructor-arg name="messageListener" ref="messageListener"/>
// </bean>
}
}
补充:问题已经找到了,应该是rocketmq客户端和服务器版本不一致的问题所致,我们公司的环境(由运维统管)使用的是3.2.6,上述出问题的客户端版本使用的是3.6.2.Final。客户端切换成3.2.6版本之后,就没有这个问题了。
参考:http://blog.csdn.net/xyzjl/article/details/54970927
rocketmq消息重复推送的问题的更多相关文章
- #研发中间件介绍#异步消息可靠推送Notify
郑昀 基于朱传志的设计文档 最后更新于2014/11/11 关键词:异步消息.订阅者集群.可伸缩.Push模式.Pull模式 本文档适用人员:研发 电商系统为什么需要 NotifyServer? ...
- PHP版微信公共平台消息主动推送,突破订阅号一天只能发送一条信息限制
2013年10月06日最新整理. PHP版微信公共平台消息主动推送,突破订阅号一天只能发送一条信息限制 微信公共平台消息主动推送接口一直是腾讯的私用接口,相信很多朋友都非常想要用到这个功能. 通过学习 ...
- Swift - 本地消息的推送通知(附样例)
使用UILocalNotification可以很方便的实现消息的推送功能.我们可以设置这个消息的推送时间,推送内容等. 当推送时间一到,不管用户在桌面还是其他应用中,屏幕上方会都显示出推送消息. 1, ...
- .NET之微信消息模板推送
最近在项目中使用到了微信消息模板推送的功能,也就是将对应的消息推送到对应的用户微信上去,前提是你必须要有一个微信公众号并且是付费了的才会有这个功能,还有就是要推送的用户必须是的关注了你的微信公众号的. ...
- dwr3实现消息精确推送详细步骤
最近项目中需要用到推送消息,找了很久终于找到一篇不错的文章,方便以后查看就转载了,也分享给大家,希望能帮到有需要的人. 第一.在项目中引入dwr.jar,然后在web.xml中进行配置,配置如下: & ...
- 基于HTTP协议之WEB消息实时推送技术原理及实现
很早就想写一些关于网页消息实时推送技术方面的文章,但是由于最近实在忙,没有时间去写文章.本文主要讲解基于 HTTP1.1 协议的 WEB 推送的技术原理及实现.本人曾经在工作的时候也有做过一些用到网页 ...
- RabbitMQ 延迟队列,消息延迟推送
目录 应用场景 消息延迟推送的实现 测试结果 应用场景 目前常见的应用软件都有消息的延迟推送的影子,应用也极为广泛,例如: 淘宝七天自动确认收货.在我们签收商品后,物流系统会在七天后延时发送一个消息给 ...
- NET SignaiR 实现消息的推送,并使用Push.js实现通知
一.使用背景 1. SignalR是什么? ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指 ...
- spring boot 集成 websocket 实现消息主动推送
spring boot 集成 websocket 实现消息主动 前言 http协议是无状态协议,每次请求都不知道前面发生了什么,而且只可以由浏览器端请求服务器端,而不能由服务器去主动通知浏览器端,是单 ...
随机推荐
- nodejs+mysql入门实例(改)
//连接数据库 var mysql = require('mysql'); var connection = mysql.createConnection({ host: 'bdm253137448. ...
- 回车和刷新以及Ctr+F5的区别
回车(url跳转)主要是判断本地缓存文件的Expires的有效时间,如果有效则直接使用客户端缓存 不在提交到HTTP服务器 F5 Expires设置不再起效果,只有Last-Modified/ETag ...
- WebSocket.之.基础入门-断开连接处理
ebSocket.之.基础入门-断开连接处理 在<WebSocket.之.基础入门-后端响应消息>的代码基础之上,继续更新代码.代码只改动了:TestSocket.java 和 index ...
- jQuery-表格属性
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- jQuery-手风琴效果-2
动画 高级函数:基于底层函数又进行了封装 两大块:简化版的动画函数和万能动画函数 简化版动画函数 显示/隐藏$().show; $(...).hide(); 强调:无参数的show()/hide()使 ...
- SV通过DPI调用C
Verilog与C之间进行程序交互,PLI(Programming Language Interface)经过了TF,ACC,VPI等模式. 使用PLI可以生成延时计算器,来连接和同步多个仿真器,并可 ...
- python 文件写入错误
在保存网页文字到txt文件下时,出现如下错误 UnicodeEncodeError: 'gbk' codec can't encode character u'\xa9' in position 24 ...
- Marlin 溫度 sensor 校正
Marlin 溫度 sensor 校正 使用 Type-K 溫度計 將探針綑綁在加熱頭側面 開啟Marlin-Marlin_v1\Marlin\thermistortables.h 要修改的溫度對應表 ...
- SiteCore Experience Analytics-体验分析
体验分析 Sitecore Experience Analytics为营销人员和营销分析师提供仪表板和报告,以识别从其网站和可能的其他外部数据源收集的体验数据的模式和趋势. 体验分析报告示例: ...
- Sitecore系统教程之模板理解
Sitecore中的所有内容都是一个项目.模板也是如此.Sitecore中的模板是一个项目,它定义了其他项目的结构和行为.Sitecore中的每个项目都是某个模板的实例.模板还可以定义它分解成的部分和 ...