大多数状况下,使用消息队列目的是::解耦、异步、削峰。redis
经过一个 MQ,Pub/Sub 发布订阅消息这么一个模型,完全解耦了数据库
经过MQ,使得同步的操做变为异步操做,提升效率。架构
经过MQ,控制服务能够接收到的请求数量并发
优势就是在特殊场景下有其对应的好处,解耦、异步、削峰异步
缺点有如下几个:分布式
系统可用性下降性能
系统引入的外部依赖越多,越容易挂掉。须要保证消息队列的高可用大数据
系统复杂度提升,保证消息没有重复消费,怎么处理消息丢失的状况,怎么保证消息传递的顺序性?头大头大,问题一大堆,痛苦不已。优化
一致性问题spa
A 系统处理完了直接返回成功了,人都觉得你这个请求就成功了;可是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。
ack(消费者确认)(消费者手动ack)
持久化 (交换机、队列、消息)
不推荐使用消息事务,会验证下降性能
生产者确认(publisher confirm):生产者发送消息后,等待mq的ACK,若是没有收到或者收到失败信息,则重试。若是收到成功消息则业务结束。
channel.waitForConfirmsOrDie(10000);
可靠消息服务(可选,本身编写逻辑):对于部分不支持生产者确认的消息队列,能够发送消息前,将消息持久化到数据库,并记录消息状态,后续消息发送、消费等过程都依赖于数据库中消息状态的判断和修改。
经过同一个队列多消费者监听,实现消息的争抢,加快消息消费速度。
答:大部分业务对消息的有序性要求不高,若是遇到对时序要求较高的业务,分两种状况来处理:
业务同时对并发要求不高:
保证消息发送时有序同步发送
保证消息发送被同一个队列接收
保证一个队列只有一个消费者,能够有从机(待机状态),实现高可用。
实现主从(Zookeeper集群选主)
业务同时对并发要求较高:
知足上述第一个场景的条件
能够有多个队列
有时序要求的一组消息,经过hash方式分派到一个固定队列 2 hash -> klsdilelksd
保证接口幂等便可,那么如何保证接口幂等呢?
某些接口天生幂等,例如查询请求
某些接口天生不幂等,好比新增,还有某些接口的修改功能
1 - 消息已接收 2- 消息正在处理 3- 已处理完毕
update set stat =3 where id =2 and stat =2
能根据具体的业务或状态来肯定的,在消费端经过业务判断是否执行过
msgid 转帐的短信id=123 - 》 123456 redis msgid -> 123456,userid
特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
---|---|---|---|---|
单机吞吐量 | 万级,比 RocketMQ、Kafka 低一个数量级 | 同 ActiveMQ | 10 万级,支撑高吞吐 | 10 万级,高吞吐,通常配合大数据类的系统来进行实时数据计算、日志采集等场景 |
topic 数量对吞吐量的影响 | topic 能够达到几百/几千的级别,吞吐量会有较小幅度的降低,这是 RocketMQ 的一大优点,在同等机器下,能够支撑大量的 topic | topic 从几十到几百个时候,吞吐量会大幅度降低,在同等机器下,Kafka 尽可能保证 topic 数量不要过多,若是要支撑大规模的 topic,须要增长更多的机器资源 | ||
时效性 | ms 级 | 微秒级,这是 RabbitMQ 的一大特色,延迟最低 | ms 级 | 延迟在 ms 级之内 |
可用性 | 高,基于主从架构实现高可用 | 同 ActiveMQ | 很是高,分布式架构 | 很是高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会致使不可用 |
消息可靠性 | 有较低的几率丢失数据 | 基本不丢 | 通过参数优化配置,能够作到 0 丢失 | 同 RocketMQ |
功能支持 | MQ 领域的功能极其完备 | 基于 erlang 开发,并发能力很强,性能极好,延时很低 | MQ 功能较为完善,仍是分布式的,扩展性好 | 功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用 |
中小型公司,技术实力较为通常,技术挑战不是特别高,用 RabbitMQ 是不错的选择;
大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。
若是是大数据领域