消息队列面试
一、消息队列应用场景
异步处理
场景说明:用户注册后,需要发注册邮件和注册短信。传统的做法有两种 1.串行的方式;2.并行方式。
(1)串行方式:将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务全部完成后,返回给客户端。
(2)并行方式:将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成后,返回给客户端。与串行的差别是,并行的方式可以提高处理的时间。
应用解耦
场景说明:用户下单后,订单系统需要通知库存系统。传统的做法是,订单系统调用库存系统的接口。如下图
传统模式的缺点:
假如库存系统无法访问,则订单减库存将失败,从而导致订单失败
订单系统与库存系统耦合
如何解决以上问题呢?引入应用消息队列后的方案,如下图:
订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功
库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操作
假如:在下单时库存系统不能正常使用。也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。实现订单系统与库存系统的应用解耦
流量削锋
流量削锋也是消息队列中的常用场景,一般在秒杀或团抢活动中使用广泛
应用场景:秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。
日志处理
日志处理是指将消息队列用在日志处理中,比如Kafka的应用,解决大量日志传输的问题。架构简化如下
日志采集客户端,负责日志数据采集,定时写受写入Kafka队列
Kafka消息队列,负责日志数据的接收,存储和转发
日志处理应用:订阅并消费kafka队列中的日志数据
二、如何保证消息不丢失
1、确保消息送到MQ:消息确认机制(Confirm模式)。
2、确保消息路由到正确队列:路由失败通知,可以将失败的消息返回给生产者,重新投递。
3、确保消息在队列中正确存储:交换机、队列、消息持久化。
4、确保队列的消息正确投递给消费者:手动确认模式、消费者处理完毕后确认。
三、消息重复消费,如何解决重复消费?
基本都是消息投/消费后没有正确回复MQ,导致的重复投/消费。
1、要求消息的幂等性。
2、MVCC多版本并发控制:乐观锁的一种实现。也就是说,生产者发送消息要带上版本号,消费者更新时,对比版本号,若不一致则无法成功。
3、去重表:利用数据库表的特性来实现幂等性,表上建立一个唯一索引,保证某一类数据一旦执行完毕,后续同样的请求不在处理了。比如:利用日志表来记录处理成功的消息ID。
四、如何进行RocketMQ的性能调优
JVM层面
暂停监控
消除偏向锁:RockeMQ都是多线程操作,没必要使用偏向锁,通过JVM参数:-XX:-UseBiasedLocking禁用偏向锁。
垃圾回收参数:
-Xms8G -Xmx8G -Xmn4G -XX:+UseG1GC堆空间,年轻代多给一点内存,RockeMQ推荐使用G1垃圾回收器。-XX:G1HeapRegionSize=16MG1收集器的region(区域)大小设置为16M.-XX:G1ReservePercent=25G1管理老年代里预留25%的空闲内存,保证新生代对象进入老年代时,有足够的空间。-XX:initiatingHeapOccupancyPercent=30当堆内存使用率达到30%后自动启动G1的并发垃圾回收。
操作系统层面
基本参数
vm.overcommit_memory=1是否允许内存过量分配{0:当用户申请内存时,内核去检查是否有这么大的内存,1:内核始终认为,是有足够的内存空间,直到他用完为止,2:内核禁止任何形式的过量分配内存}vm.swappiness=10swappiness=0:仅在内存不足的情况下,当空闲内存低于vm.min_free_bkytes_limit时,使用交换空间。swappiness=1:内核版本3.5及以上、Red Hat内核版本2.6.32-303及以上,尽量少用交换空间。swappiness=10:当前系统内存足够时,推荐设置,可提高性能。swappiness=60:默认值。swappiness=100:内核将积极的使用交换空间。vm.max_max_count=655360定义了一个进程能拥有最多的线程。ulimit=1000000limits.conf设置用户能打开的最大文件数。
网卡
关闭IROBalanceIROBalance主要功能是可以合理利用调度分配到各个CPU核心上,特别针对目前主流多核心CPU,但是实际往往影响CPU使用的均衡性。建议关闭。TCP NODEALYNagle算法用于对缓冲区内的一定数量的消息进行自动连接。该处理过程成为Nagling,通过减少必要发送的封包数量,提高网络应用程序系统的效率(Nagle虽然解决了小封包问题,但是也导致了较高的不可预期的延迟,同时降低了吞吐量,所以不需要开启Nagle算法)。
版权声明
非特殊说明,本文由Zender原创或收集发布,欢迎转载。
ZENDER






发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。