实战:如何防止mq消费方消息重复消费

如果因为网络延迟等原因,mq无法及时接收到消费方的应答,导致mq重试。(计算机网络)。在重试过程中造成重复消费的问题
解决思路:
1)如果消费方是做数据库操作,那么可以把消息的id,在重试的情况下,会触发主键冲突,从而避免数据出现脏数据。(也可以先用消息id或其他唯一标识去查找表是否存在数据,存在,不插入;不存在,插入)
2)如果消费方不是做数据库操作,可以借助第三方应用,如redis,来记录消费记录。每次消息被消费完成的时候,把当前消息的id作为key存入redis,每次消费前,先去redis查询有没有该消费记录

理论概述

rocketmq是消息中间件,是一种队列,先进先出。
主要实现异步功能
生产者使用封装rocketmq的sendMsg发送消息到消息中间件完成了发送消息的过程。
消费者从mq中获取消息,进行消费。生产者和消费者之间是低耦合的,独立的完成自己的任务。
完成了异步和解耦

WHY?

解决了什么问题

实战:如何防止mq消费方消息重复消费、rocketmq理论概述、rocketmq组成、普通消息的发送_解耦

之前如果一个订单服务分别调用支付服务、物流服务、库存服务等等里面的方法,如果说其中一个服务挂了,那么整个业务就无法执行的--------一般非核心业务。

那么mq实现解耦功能,让核心业务和非核心业务解耦,让各个服务解耦。这样即使一些比如物流服务挂了,支付业务还是能正常执行,后面对物流服务做一个补偿机制。

实战:如何防止mq消费方消息重复消费、rocketmq理论概述、rocketmq组成、普通消息的发送_发送消息_02


流量削峰,rockmq天生为高并发的秒杀服务的。没有使用mq的普通情况,多少请求就会到A系统,如果秒杀每秒5000次请求过去了,这个时候mysql说我最大只能每秒200请求,多了我受不了,系统接口直接查询慢或者卡住了直到超时。那么所有人都卡在这里,无法选出前200秒秒杀成功的用户。并且太多的请求堆积在A系统,最终可能导致A系统的崩溃。

而mq来了,你生产者可以生产出每秒5000次,5000次消息到mq了,mq本身是高并发请求接受率比较高的系统,可以解决高峰问题,生产者任务完成了,你没有事了。而我消费者一个服务一秒只能最大消费200请求,拉取消息200,先来的先消费,我这一秒只消费200,其他的消息你再等一等,我现在没空。知道所有消息消费完毕。

秒杀请求可以请求过来,但是要先到的200个我让你这一秒秒杀成功,后来的库存还有就可以消费,库存没有就秒杀结束。
保证了A系统的稳定性,“用时间换空间”。

维护性良好生产者业务改动的较少,一般改不同消费者去消费消息。很方便做到一些消息业务删除,增加,修改。
没有使用mq的以前模式,那么改动可能消费者服务改一下,生产者服务改一下,严格意义没有所谓的生产者、消费者一说。

补充:集群:多个服务器服务一个任务
微服务:一个服务对应一个任务,是分布式的一种方式。

rocketmq组成

rocketmq:
accessKey: LTAI4FzV************
secretKey: UzhGN*************************
nameSrvAddr: localhost:8100;localhost:8100
consumerGroups:
- groupId: GID-********
consumers:
- topic: TOPIC-*****
tag: DING-****
beanName: one**************Listener
- groupId: GID-***********
consumers:
- topic: TOPIC-*****
tag: AD-*******
beanName: user*********Listener

Group:分组,对消费者用处较大,比如分为物流组、库存组,每个消费者消费自己所在的组,互不干扰,相对独立进行。

Topic:主题,一类消息的主题或分类,电商可能衣服是个主题、鞋子是主题;也有根据业务服务来定义的,比如报告服务一类主题、采集服务一类主题、品牌服务一类主题。

消费队列:topic可以生成一条消息队列,也可以多条消息队列。

实战:如何防止mq消费方消息重复消费、rocketmq理论概述、rocketmq组成、普通消息的发送_解耦_03


一个queue被一个consumer消费,并且messageQueue1---->consumer1,messageQueue2---->consumer2

提高了消费并发度。

tag:topic基础在还可以在分类,比如topic是手机,tag可以进一步细分苹果手机。
可以让指定消费者只消费苹果手机。

普通消息的发送

同步发送

确保发送成功,一些重要的消息,短信通知,应用消息通知,发送消息后,需要同步响应后再次发送消息。

实战:如何防止mq消费方消息重复消费、rocketmq理论概述、rocketmq组成、普通消息的发送_发送消息_04

异步发送
发送数据量大,对响应速度敏感的场景。
发送消息后不用等响应,接着可以发送消息。不会阻塞发送消息线程

实战:如何防止mq消费方消息重复消费、rocketmq理论概述、rocketmq组成、普通消息的发送_redis_05

单向发送

速度快,对可靠性要求不高

由于在 oneway 方式发送消息时没有请求应答处理,一旦出现消息发送失败,则会因为没有重试而导致数据丢失。

若数据不可丢,建议选用同步或异步发送方式。

实战:如何防止mq消费方消息重复消费、rocketmq理论概述、rocketmq组成、普通消息的发送_开发语言_06

普通消息

有集群消费和广播消费两种

集群消费用的多些,保证数据完整性。

实战:如何防止mq消费方消息重复消费、rocketmq理论概述、rocketmq组成、普通消息的发送_开发语言_07


全局消息

一个生产者-----》一个消费者

先进先出

来一个消费一个

部分顺序消息
一个生产者----->多个消费者
每个消费者对应消费不同的QueueX
所以称局部按照先进先出的原则来的。

延时消息
18个等级
message.setDelayTimeLevel(3);
定时
应用在付款关闭倒计时等

还有批量消息、过滤消息等操作。

普通消息属性关系

实战:如何防止mq消费方消息重复消费、rocketmq理论概述、rocketmq组成、普通消息的发送_解耦_08

Offset:偏移量