什么是MQ
MQ是消息队列,基于队列的机制实现生产者和消费者之间的消息传递。
MQ的优缺点
1. 优点
- 解耦:系统与系统对接变成系统与MQ对接,降低了系统之间的耦合
- 异步:一些业务功能可以通过MQ异步执行,降低响应时间,提高用户体验
- 削峰:有突发流量时请求可以在MQ中排队,下游服务可以平滑处理请求。
2. 缺点
- 可用性降低:依赖服务越多,系统出现故障概率越高。MQ瘫痪会影响上下游服务。
- 复杂性提高:有消息丢失、重复消费、消息顺序性等问题
- 一致性问题:一条消息发到多个系统,如何保证结果一致。
MQ之间的对比
1. 各个MQ的强弱项
- Kafka:单机吞吐量高(10w),常用于大数据领域的实时计算的日志采集。但是功能简单
- RocketMQ:单机吞吐量高(10w-),Java开发,容易定制化,功能全。但是技术有被抛弃的风险。
- RabbitMQ:延迟低(微秒级),社区活跃。但是吞吐量低(1w级),erlang开发,不易定制。
- ActiveMQ:功能多。但是吞吐量低(1w级),有消息丢失可能
2. 对比
图片来自网络
如何避免消息丢失
如何保证消息顺序性
1. 全局顺序性
每个Topic下只有一个分区,消费者从这个分区拿到的消息是顺序的
2. 局部顺序性
每个Topic下可以有多个分区。但是某些消息只能进到相同分区。(比如相同的人和订单的增删改查操作只能进入一个分区,保证了这个人在这个订单上增删改查的顺序性)
消息堆积的原因及处理方法
1. 消息堆积的原因
2. 消息堆积的危害
- 消息过期被丢弃
- 磁盘满了,无法接收新消息
- 海量消息等待消费,消费时间晚,消费者压力大
3. 避免消息堆积或解决消息堆积
- 消息过期:
- 不设置消息过期时间
- 设置过期时间后发生消息丢失,需要人工找出丢失的消息重新发送到队列
- 磁盘满:创建临时消费者,将消息取出来发送到临时MQ,最后让原来的消费者消费。
- 快速消费:
- 分区扩容、加消费者(分区扩容后无法缩容)
- 临时consumer发送到临时队列上,临时队列可以有多个分区,因此可以增加消费者(麻烦)
- 多线程消费(注意乱序问题)
消息重复消费怎么解决
1. 重复消费原因
- MQ接收了生产者的消息,但是生产者没接收到MQ的确认,导致生产者生产了两条消息
- 消费者消费消息后,MQ未接收到消费者的确认信息,导致消费者重复消费
2. 解决方法
1. 生产端
启动kafka的幂等性,避免接收生产者的重复消息
修改配置文件:enable.idempotence=true 同时要求 ack=all 且 retries>1。
判断生产者发送消息的状态id,如果当前id小于kafka记录的生产者id,则说明消息已经接收过,不再接受。
2. 消费端
下游做幂等
如何设计一个消息队列
参照kafka,有如下几个角度
参考