1. 消息队列的应用场景
异步,削峰,解耦
扩展:消息队列最基本的目的就是解决生产者和消费者之间速度不匹配的问题。
2. 使用消息队列的优点
(1)异步化,提高系统响应速度。
(2)系统解耦,提高系统稳定性。
(3)消除峰值
3. 使用消息队列的缺点
(1)依赖的服务增多,系统可用性降低。
(2)系统复杂性提高
(3)会导致数据一致性问题。A系统处理完了直接返回成功,大家都以为这个请求已经成功了,但其实消费者(BCD)那边,可能BD执行成功了,C失败了。
4. 消息队列的特性
(1)业务无关
(2)FIFO(先进先出)
(3)容灾。结点的动态增删和消息的持久化是其支持容灾能力的基本特性。
5.几种MQ队列的比较
特性 | ActiveMQ | RabbitMQ | RocketMQ | kafka |
---|---|---|---|---|
单机吞吐量 | 万级 | 万级 | 十万级 | 十万级 |
topic数量对吞吐量的影响 | topic达到几百、几千的时候,吞吐量会有小幅度下降(优点) | topic从几十到几百的时候,吞吐量会大幅度下降(如果需要支撑大规模的topic,需要增加更多的机器资源) | ||
时效性 | 毫秒 | 微秒 | 毫秒 | 毫秒 |
可用性 | 高,主从架构 | 高,主从架构 | 非常高,分布式架构 | 非常高,分布式架构 |
消息可靠性 | 有较低的丢失概率 | 基本不丢 | 经过优化配置,可以做到0丢失 | 经过优化配置,可以做到0丢失 |
功能支持 | 功能完备 | 并发能力强,性能好,延时低 | 功能较为完备,分布式,扩展性好 | 功能简单,在大数据领域的实时计算以及日志采集被大规模使用 |
应用场景 | 没经过大规模吞吐量场景的验证,社区不活跃,不推荐 | erlang语言阻止了java工程师研究,对公司而言,处于不可控状态,开源,活跃,推荐中小型公司使用 | 阿里出品,社区不活跃,推荐大型公司,有基础架构研发实力的公司使用 | 大数据领域的实时计算以及日志采集被大规模使用 |
6. 如何保证消息100%投递成功
(1)一般的消息中间件为了提高系统的吞吐量会把消息保存在内存中,如果不做其他处理,MQ服务宕机,会造成消息丢失。
针对上述情况可以将消息持久化到磁盘文件中。
(2)那如果消息刚保存到内存中,还没来得及持久化到磁盘中,服务器就宕机了怎么办?
产生上述问题的原因在于我们不知道消息是否持久化成功,这里可以用消息队列的confirm机制,生产者发送消息,如果接收成功,会返回ack;如果接收失败,MQ返回nack消息。但是如果每次发送消息都需要持久化,会导致MQ吞吐量降低。其实MQ持久化到磁盘的实现是异步调用的,比如:等到有几千条消息的时候,会一次性刷盘到磁盘上。
但是这样还是会存在有一部分消息会丢失的风险?那怎么办呢?消息提前持久化+定时任务
定时任务上还可以在加上一个补偿机制次数,如果大于3,还是没有收到ack消息,则将次消息标志为失败,由人工去排查。
接下来需要解决的问题就是要求消费者在消费的时候如何保障幂等了。
7.如何保证消息的幂等
(1)乐观锁,每次操作的时候带一个版本号,看调用方的版本号和被调用方的版本号是否一致,如果一致,则执行;如果不一致,则不执行。
(2)唯一Id+指纹码
(3)redis原子操作