目录
来自于《石杉码农》视频
一、消息队列作用
为什么使用消息队列
1、异步
不关系返回值
考虑多线程?
高延迟,一个请求消耗过长
对于不关心返回时,可以将请求发送队列中,然后由其余系统处理
2、解耦
不方便扩展,当需要增加新系统时,则需要重新修改A系统
增加MQ之后,业务系统只需要从MQ中消费即可,而无需系统A改动,而且系统A无需考虑调用失败与否
(pub/sub模型)
3、消峰
将MQ引入之后,将其当做一个水库,所有上游的流量都在水库里进行留存,然后下游可以慢慢消费
水库冲垮怎么办??
引入之后的缺点:
- 系统可用性降低:你想啊,本来其他系统只要运行好好的,那你的系统就是正常的。现在你非要加个消息队列进去,那消息队列挂了,你的系统不是呵呵了。因此,系统可用性降低(这个存疑。。。。)
- 系统复杂性增加:要多考虑很多方面的问题,比如一致性问题、如何保证消息不被重复消费,如何保证保证消息可靠传输。因此,需要考虑的东西更多,系统复杂性增大。
二、选型
kafka、rabbitmq,activemq,rocketmq
三、rabbitmq高可用性的保证
普通模式:无法实现真实的高可用
镜像集群:非分布式
四、kafka的高可用解决方案
https://www.jianshu.com/p/d3e963ff8b70
脑裂怎么解决?
https://www.cnblogs.com/wxzhe/p/10195916.html
五、消息重复消费
幂等
消费者消费消息是按照offset顺序,消费完之后,会提交offset到sk中
消费者是定时、定期提交offset,假如在提交之前重启了,则会产生重复消费的问题
根据业务的特点,考虑系统的幂等性
六、rabbitmq怎么避免消息丢失
1、生产者丢失数据
- 利用mq的事务功能
- 2.利用confirm机制,回调机制,优于事务机制,吞吐量高于事务机制
2、rabbitmq
开启持久化,可能出现,尚未持久化就挂了的情况
3、消费者端
不要开启autoAck,进行手动ack
七、kafka丢失数据
1、生产者
2、kafka丢失数据
3、消费者端
不要自动提交
八、怎么保证消息的顺序性
需要保证顺序性的消息都放入同一个queue中
kafka保证顺序性:利用了一个key一定会进入一个partition中,并且一个消费者只能顺序消费一个partition中的消息
发生错乱的情形:如果一个消费者有三个线程在消费,则可能出现顺序性问题
利用某种数据的特性,比如订单id,可以每一个线程增加一个内存队列,则根据算法,将同一个订单的消息都处理进入同一个内存队列,这样也就保证了顺序性