什么是幂等性:

在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。

当出现消费者对某条消息重复消费的情况时,重复消费的结果与消费一次的结果是相同的,并且多次消费并未对业务系统产生任何负面影响,那么这整个过程就实现可消息幂等。

例如,在支付场景下,消费者消费扣款消息,对一笔订单执行扣款操作,扣款金额为 100 元。

如果因网络不稳定等原因导致扣款消息重复投递,消费者重复消费了该扣款消息,但最终的业务结果是只扣款一次,扣费 100 元,

且用户的扣款记录中对应的订单只有一条扣款流水,不会多次扣除费用。那么这次扣款操作是符合要求的,整个消费过程实现了消费幂等。

实例:

在RocketMQ中因为 Message ID 有可能出现冲突(重复)的情况,所以真正安全的幂等处理,不建议以 Message ID 作为处理依据。

最好的方式是以业务唯一标识作为幂等处理的关键依据,而业务的唯一标识可以通过消息 Key 设置。

下面模拟:

生产者

package com.wish.retry;

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; public class RetryProducer {
public static void main(String[] args) throws MQClientException {
DefaultMQProducer producer = new DefaultMQProducer("retry_rmq-group");
producer.setNamesrvAddr("192.168.152.55:9876;192.168.152.66:9876");
producer.setInstanceName("retry_producer");
producer.start();
try {
for (int i = 0; i < 1; i++) {
Thread.sleep(1000); // 每秒发送一次MQ
Message msg = new Message("itmayiedu-topic", // topic 主题名称
"TagA", // tag 临时值
("retry_itmayiedu-6" + i).getBytes()// body 内容
);
msg.setKeys(System.currentTimeMillis() + "");
SendResult sendResult = producer.send(msg);
System.out.println(sendResult.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
producer.shutdown();
} }

  

消费者

package com.wish.retry;

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.message.MessageExt;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class RetryConsumer {
static private Map<String, String> logMap = new HashMap<>(); public static void main(String[] args) throws MQClientException {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("retry_rmq-group"); consumer.setNamesrvAddr("192.168.152.55:9876;192.168.152.66:9876");
consumer.setInstanceName("retry_consumer");
consumer.subscribe("retry_itmayiedu-topic", "TagA"); consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
String key = null;
String msgId = null;
try {
for (MessageExt msg : msgs) {
key = msg.getKeys();
if (logMap.containsKey(key)) {
// 无需继续重试。
System.out.println("key:"+key+",无需重试...");
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
msgId = msg.getMsgId();
System.out.println("key:" + key + ",msgid:" + msgId + "---" + new String(msg.getBody()));
int i = 1 / 0;
} } catch (Exception e) {
e.printStackTrace();
return ConsumeConcurrentlyStatus.RECONSUME_LATER;
} finally {
logMap.put(key, msgId);
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();
System.out.println("RetryConsumer Started.");
}
}

  

RocketMQ幂等性问题的更多相关文章

  1. rocketmq(三 java操作rocket API, rocketmq 幂等性)

    JAVA操作rocketmq: 1.导入rocketmq所需要的依赖: <dependency> <groupId>com.alibaba.rocketmq</group ...

  2. RocketMQ解决幂等性问题

    一.造成重复消费的原因 在于回馈机制.正常情况下,消费者在消费消息时候,消费完毕后,会发送一个ACK确认信息给消息队列(broker),消息队列(broker)就知道该消息被消费了,就会将该消息从消息 ...

  3. RocketMQ 原理:消息存储、高可用、消息重试、消息幂等性

    目录 消息存储 消息存储方式 非持久化 持久化 消息存储介质 消息存储与读写方式 消息存储结构 刷盘机制 同步刷盘 异步刷盘 小结 高可用 高可用实现 主从复制 负载均衡 消息重试 顺序消息重试 无序 ...

  4. 分布式开放消息系统(RocketMQ)的原理与实践

    分布式消息系统作为实现分布式系统可扩展.可伸缩性的关键组件,需要具有高吞吐量.高可用等特点.而谈到消息系统的设计,就回避不了两个问题: 消息的顺序问题 消息的重复问题 RocketMQ作为阿里开源的一 ...

  5. 分布式开放消息系统(RocketMQ)的原理与实践(转)

    转自:http://www.jianshu.com/p/453c6e7ff81c 分布式消息系统作为实现分布式系统可扩展.可伸缩性的关键组件,需要具有高吞吐量.高可用等特点.而谈到消息系统的设计,就回 ...

  6. RocketMQ入门

    本文首先引出消息中间件通常需要解决哪些问题,在解决这些问题当中会遇到什么困难,Apache RocketMQ作为阿里开源的一款高性能.高吞吐量的分布式消息中间件否可以解决,规范中如何定义这些问题.然后 ...

  7. 入门rocketmq从浅到深

    目录 一.引言 二.介绍 三.Rocketmq关键概念 1.主题与标签 2.发送与订阅群组 3.Broker与NameServer 4.广播消费与集群消费 5.消息队列 6.集群方式 7.顺序消息 8 ...

  8. rocketmq (一)运行原理以及使用问题

    使用消息中间件可以解决高并发,那是因为消息中间件可以将消息缓存到队列之中. 但是 当消息 过多的时候,几万,几十万...消息中间件也可能会宕机,所以我们可以对消息中间件进行集群,在之前的activem ...

  9. 分布式消息中间件rocketmq的原理与实践

    RocketMQ作为阿里开源的一款高性能.高吞吐量的消息中间件,它是怎样来解决这两个问题的?RocketMQ 有哪些关键特性?其实现原理是怎样的? 关键特性以及其实现原理 一.顺序消息 消息有序指的是 ...

随机推荐

  1. python 不可变字典 inmutabledict的实现

    python inmutabledict的实现 关于在python中如何实现不可变字典的方法.早在pep416中,就建议python官方实现inmutabledict,但是官方否认了.理由主要是 根据 ...

  2. 4..部署场景2:带有遗留的Linux Bridge

    此场景描述了使用Linux bridge的ML2插件实现OpenStack网络服务的遗留(基本)实现. 遗留实现通过为常规(非特权)用户提供一种方法来管理一个项目中的虚拟网络,并包含以下组件:提供了自 ...

  3. 14、 NAT

    私有IP地址段:10.0.0.0-10.255.255.255/8172.16.0.0-172.31.255.255/12192.168.0.0-192.168.255.255/16 NAT的必要性: ...

  4. 04讲基础篇:经常说的CPU上下文切换是什么意思(下)

    具体分析 自愿上下文切换变多了,说明进程都在等待资源,有可能发生了 I/O 等其他问题: 非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢 CPU,说明 CPU 的确成了瓶颈: 中断次数 ...

  5. FFMPEG学习----使用SDL构建音频播放器

    ffmpeg版本:ffmpeg-20160413-git-0efafc5 #include <stdio.h> #include <stdlib.h> #include < ...

  6. VC运行时库/MD、/MDd、/MT、/MTd说明

    http://blog.csdn.net/holybin/article/details/26134153 VC运行时库设置:VC项目属性->配置属性->C/C++->代码生成-&g ...

  7. 曹工说Spring Boot源码(17)-- Spring从xml文件里到底得到了什么(aop:config完整解析【中】)

    写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...

  8. mongodb 常用操作命令

    1.关闭mongodbuse admindb.shutdownServer() 2.报错 not master and slaveok=falsers.slaveOk(); 3.查看集群副本的状态rs ...

  9. 微信小程序面试题总结

    A类问题 1 请谈谈微信小程序主要目录和文件的作用? project.config.json 项目配置文件,用得最多的就是配置是否开启https校验: App.js 设置一些全局的基础数据等: App ...

  10. css中伪类和伪元素

    伪类和伪元素时对那些我们不能通过class.id等选择元素的补充 伪类的操作对象是文档树中已有的元素(可以给已有元素加了一个类替代),而伪元素则创建了一个文档数外的元素(可以添加一个新元素替代) CS ...