什么是幂等性:

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

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

例如,在支付场景下,消费者消费扣款消息,对一笔订单执行扣款操作,扣款金额为 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. Arduino系列之pwm控制LED灯(呼吸灯)

    下面我将写出最简单控制呼吸灯的方法 void setup()                                 // { pinMode(12,OUTPUT);             ...

  2. python中os模块的一些小总结

    (一)os模块的应用小总结 os.name: 获取当前系统平台,Windows下返回'nt',Linux下返回'posix'.   os.linesep: 获取当前平台使用的行终止符.Windows下 ...

  3. javase第一章(了解java)

    ------------恢复内容开始------------ java介绍 java这门语言,如果你是一名IT从业者,那么就一定是会有所耳闻的,毕竟,这是编程史上其商业化最成功的一门语言,当然, 编程 ...

  4. FFMPEG学习----解码视频

    基础概念 我们平时看到的视频文件有许多格式,比如 avi, mkv, rmvb, mov, mp4等等,这些被称为容器(Container), 不同的容器格式规定了其中音视频数据的组织方式(也包括其他 ...

  5. Simscape Multibody 教程 —— 入门学习

    写在前面 本文要点: Simscape Multibody 简介 Simscape Multibody 入门学习的推荐学习材料和学习顺序 建模仿真过程中的重要知识 模型的参数设置(Model Work ...

  6. Flink与HanLP集成使用

    自然语言处理是机器学习的一个重要分支,在智能翻译.智能问答.舆情监控.ChatOps等都有很好的应用场景,目前比较好的一个开源实现工具是何晗大神的HanLP,主页(http://hanlp.com/) ...

  7. java架构之路-(netty专题)netty的编解码(出入战)与粘包拆包

    上次回归: 上次博客我们主要说了netty的基本使用,都是一些固定的模式去写的,我们只需要关注我们的拦截器怎么去写就可以了,然后我们用我们的基础示例,改造了一个简单的聊天室程序,可以看到内部加了一个S ...

  8. Apache 相关 mod_rewrite ,RewriteCond,{HTTP_HOST}

    1.给子域名加www标记  RewriteCond %{HTTP_HOST} ^([a-z.]+)?example\.com$ [NC] RewriteCond %{HTTP_HOST} !^www\ ...

  9. golang 运算符

    /* 算术运算符 : + - * / % ++ -- 关系运算符 : == != > < >= <= 逻辑运算符 : && || ! 赋值运算符 : = += ...

  10. nginx单个ip访问频率限制

    一.限制所有单个ip的访问频率 1.http中的配置 http { #$limit_conn_zone:限制并发连接数 limit_conn_zone $binary_remote_addr zone ...