重庆川九建设有限责任公司官方网站,外贸软件好用的,网站怎么更新数据,千库网原创设计师分析#xff1a;这个问题其实换一种问法就是#xff0c;如何保证消息队列的幂等性#xff1f;这个问题可以认为是消息队列领域的基本问题。换句话来说#xff0c;是在考察你的设计能力#xff0c;这个问题的回答可以根据具体的业务场景来答#xff0c;没有固定的答案。 回…分析这个问题其实换一种问法就是如何保证消息队列的幂等性这个问题可以认为是消息队列领域的基本问题。换句话来说是在考察你的设计能力这个问题的回答可以根据具体的业务场景来答没有固定的答案。 回答先来说一下为什么会造成重复消费 其实无论是哪种消息队列造成重复消费原因其实都是类似的。正常情况下消费者在消费消息的时候消费完毕后会发送一个确认消息给消息队列消息队列就知道该消息被消费了就会将该消息从消息队列中删除。只是不同的消息队列发出的确认消息形式不同例如RabbitMQ是发送一个ACK确认消息RocketMQ是返回一个CONSUME_SUCCESS成功标志kafka实际上有个offet的概念简单说一下就是每一个消息都有一个offsetkafka消费过消息后需要提交offset让消息队列知道自己已经消费过了。
那造成重复消费的原因就是因为网络传输等等故障确认信息没有传送到消息队列导致消息队列不知道自己已经消费过该消息了再次将消息分发给其他的消费者。
其实重复消费不可怕可怕的是你没考虑到重复消费之后怎么保证幂等性。
假设你有个系统消费一条往数据库里插入一条要是你一个消息重复两次你不就插入了两条这数据不就错了但是你要是消费到第二次的时候自己判断一下已经消费过了直接扔了不就保留了一条数据 一条数据重复出现两次数据库里就只有一条数据这就保证了系统的幂等性 幂等性我通俗点说就一个数据或者一个请求给你重复来多次你得确保对应的数据是不会改变的不能出错。
如何解决这个问题针对业务场景来答分以下三种情况
1比如你拿到这个消息做数据库的insert操作那就容易了给这个消息做一个唯一的主键那么就算出现重复消费的情况就会导致主键冲突避免数据库出现脏数据。
2再比如你拿到这个消息做redis的set的操作那就容易了不用解决因为你无论set几次结果都是一样的set操作本来就算幂等操作。
3如果上面两种情况还不行上大招。准备一个第三方介质来做消费记录。以redis为例给消息分配一个全局id只要消费过该消息将id,message以K-V形式写入redis.那消费者开始消费前先去redis中查询有没有消费记录即可,先根据这个id去比如redis里查一下之前消费过吗如果没有消费过你就处理然后这个id写redis。如果消费过了那你就别处理了保证别重复处理相同的消息即可。