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

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. TVTK安装

    首先感觉到的一点就是在https://www.lfd.uci.edu/~gohlke/pythonlibs/#chaco这个比较受欢迎的下载Python库的网站上下载大于20mb的whl文件时就很可能 ...

  2. [LeetCode] 系统刷题6_Linked List

    1. Dummy Node 2. Basic skills [LeetCode] 206. Reverse Linked List_Easy tag: Linked List 2. Fast slow ...

  3. Css3动画属性总汇

    http://css3lib.alloyteam.com/uilib/animation/demo1/#cta Css3动画属性总汇 Stay hungry. Stay foolish. Attent ...

  4. TensorFlow遇到的问题汇总(持续更新中......)

    1.调用tf.softmax_cross_entropy_with_logits函数出错. #原因是这个函数,不能按以前的方式进行调用了,只能使用命名参数的方式来调用. #原来是这样的: tf.red ...

  5. RMAN备份策略与异机恢复一例(续篇)

    本文是<RMAN备份策略与异机恢复一例>的续篇,继续实验验证,最终实现两个需求: 1.异机恢复临时测试的小库 2.传输归档时,实现增量传输 1.异机恢复临时测试的小库 之前异机恢复的需求已 ...

  6. WebSocket.之.基础入门-断开连接处理

    ebSocket.之.基础入门-断开连接处理 在<WebSocket.之.基础入门-后端响应消息>的代码基础之上,继续更新代码.代码只改动了:TestSocket.java 和 index ...

  7. nodejs中&#x5B89;&#x5353;&#x7AEF;的编码如何转换为中文

    借助一些模块来转换,比如,html-entities Github var Entities = require('html-entities').XmlEntities; entities = ne ...

  8. Nginx加载ngx_pagespeed模块,加快网站打开的速度

    [页面加速]配置Nginx加载ngx_pagespeed模块,加快网站打开的速度   ngx_pagespeed 是一个 Nginx 的扩展模块,可以加速你的网站,减少页面加载时间,它会自动将一些提升 ...

  9. Rpgmakermv(15) PH任务插件

    插件介绍 一个用来简单显示任务阶段的任务书 使用方法 插件安装 下载js文件放置到游戏目录/plugins目录下.打开插件管理器,选择PH_QuestBook.js并开启. 插件参数 Show in ...

  10. html5-了解元素的属性

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