最近,在公司的测试环境,遇到个问题,每次重启应用重启后,原来消费过的消息又被重复推送了一遍,消费者和生产者代码如下:

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消息重复推送的问题的更多相关文章

  1. #研发中间件介绍#异步消息可靠推送Notify

    郑昀 基于朱传志的设计文档 最后更新于2014/11/11 关键词:异步消息.订阅者集群.可伸缩.Push模式.Pull模式 本文档适用人员:研发   电商系统为什么需要 NotifyServer? ...

  2. PHP版微信公共平台消息主动推送,突破订阅号一天只能发送一条信息限制

    2013年10月06日最新整理. PHP版微信公共平台消息主动推送,突破订阅号一天只能发送一条信息限制 微信公共平台消息主动推送接口一直是腾讯的私用接口,相信很多朋友都非常想要用到这个功能. 通过学习 ...

  3. Swift - 本地消息的推送通知(附样例)

    使用UILocalNotification可以很方便的实现消息的推送功能.我们可以设置这个消息的推送时间,推送内容等. 当推送时间一到,不管用户在桌面还是其他应用中,屏幕上方会都显示出推送消息. 1, ...

  4. .NET之微信消息模板推送

    最近在项目中使用到了微信消息模板推送的功能,也就是将对应的消息推送到对应的用户微信上去,前提是你必须要有一个微信公众号并且是付费了的才会有这个功能,还有就是要推送的用户必须是的关注了你的微信公众号的. ...

  5. dwr3实现消息精确推送详细步骤

    最近项目中需要用到推送消息,找了很久终于找到一篇不错的文章,方便以后查看就转载了,也分享给大家,希望能帮到有需要的人. 第一.在项目中引入dwr.jar,然后在web.xml中进行配置,配置如下: & ...

  6. 基于HTTP协议之WEB消息实时推送技术原理及实现

    很早就想写一些关于网页消息实时推送技术方面的文章,但是由于最近实在忙,没有时间去写文章.本文主要讲解基于 HTTP1.1 协议的 WEB 推送的技术原理及实现.本人曾经在工作的时候也有做过一些用到网页 ...

  7. RabbitMQ 延迟队列,消息延迟推送

    目录 应用场景 消息延迟推送的实现 测试结果 应用场景 目前常见的应用软件都有消息的延迟推送的影子,应用也极为广泛,例如: 淘宝七天自动确认收货.在我们签收商品后,物流系统会在七天后延时发送一个消息给 ...

  8. NET SignaiR 实现消息的推送,并使用Push.js实现通知

    一.使用背景 1. SignalR是什么? ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指 ...

  9. spring boot 集成 websocket 实现消息主动推送

    spring boot 集成 websocket 实现消息主动 前言 http协议是无状态协议,每次请求都不知道前面发生了什么,而且只可以由浏览器端请求服务器端,而不能由服务器去主动通知浏览器端,是单 ...

随机推荐

  1. CentOS6.5 安装Storm集群

    1.首先安装依赖包 [root@Hadoop-NN-01 ~]# yum install uuid* [root@Hadoop-NN-01 ~]# yum install libuuid [root@ ...

  2. matplotlib画的图保存为emf格式

    在用matplotlib保存图片时,发现不能直接保存为emf格式.百度有人说要先另存为svg格式,再使用INKSCAPE软件转换成emf格式.我试了一下,发现还是不行,后来,发现先用matplotli ...

  3. MySQL数据类型--与MySQL零距离接触2-12主键约束

    定义一个主键,可以用PRIMARY KEY,也可以用KEY. 主键约束的字段禁止为空. 写入4条记录,查看它的自动编号: 自动编号确实是1 2 3 4 AUTO_INCREMENT字段必须定义为主键, ...

  4. Cocos Creator 计时器的延时循环试用方法

    *****计时器的一些运用***** //计算1次的计时器,2秒后执行 this.scheduleOnce(function(){ this.doSomething(); },2); //每隔5秒执行 ...

  5. JavaScript-switch-case-电话系统

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  6. Visual Studio下运行PowerShell脚本自增小版本号并发布到Nuget服务器上

    Visual Studio下运行PowerShell脚本自动更新项目里AssemblyInfo.cs文件的版本(自增小版本号)并发布到Nuget服务器上 附脚本[ update.ps1文件内容]: $ ...

  7. 在caffe中执行脚本文件时 报错:-bash: ./train.sh: Permission denied

    报错原因:没有权限 解决方法:chmod 777 train.sh获得权限

  8. Hotfix

    http://group.jobbole.com/6311/ http://www.jianshu.com/p/6f0ae1e364d9 http://www.mamicode.com/info-de ...

  9. kali漏洞扫描

    nmap (apt-get install nmap)          nmap从初级到高级 ------------------------------ Nessus (dpkg -i Nessu ...

  10. Python基础知识摘要

    python字典 增,删,改,查 1.增:XXX[新的key] = value 2.删:DEL XXX[key] 3.改:XXX[已经存在的key] = NewValue 4.查:aList.exte ...