当前位置:   article > 正文

erlang rabbitmq源码解析_RabbitMQ面试宝典,赶紧收藏!

rabitmq-erlang源

是什么?

RabbitMQ是基于Erlang语言开发的开源消息队列系统,基于AMQP协议实现。

为什么要引入消息中间件

系统解耦

一个服务要给其他十个服务提供接口,当下游其他十个服务一发生变化或者产生新的需求就会导致这一个服务改代码,显然之间的耦合性较大。为了解决耦合性过大的问题,采用MQ中间件来实现系统解耦。

系统A把自己的消息发送到MQ中间件,其他系统需要就去调用消费,不需要了就不用消费。

42ed65382f64a44167a279982da743b4.png

流量削锋

每天10点到10点5分都有一个抢杀活动进行,因为这个重新部署n台服务器是比较消耗资源的,因为就那么几分钟,其他时间这个机器都是空闲的。为了解决这个问题,我们在原本的每台机器前面都部署一层MQ,一旦到了瞬时高峰,可以将请求积压到MQ里面,等高峰期过来,再消费一段时间,MQ里面堆积的消息就消费完毕了。

9e8bfc051f7732f5b840cc74fe0cb179.png

异步调用

举个例子,点个外卖,咔嚓一下子下订单然后付款了,此时账户扣款、创建订单、通知商家给你准备菜品。骑手给你送餐?那这个找骑手的过程,是需要一套复杂算法来实现调度的,比较耗时。

但是其实稍微晚个几十秒完成骑手的调度都是ok的,因为实际并不需要在你支付的一瞬间立马给你找好骑手,也没那个必要。

找骑手这个操作很长,所以系统C发送消息到 mq,系统D消费到消息之后再异步处理。跟前面的就不一起处理了,这样对于用户来说下完单之后就直接显示成功了。

67495e8d31d3b921729899c990783fad.png

有哪些消息中间件?

ActiveMQ:老牌的消息中间件,没法确认可以支撑互联网公司的高并发、高负载以及高吞吐的复杂场景,在国内互联网用的较少,主要是一些传统企业,用来做异步调用和系统解耦。

RabbitMQ:支持高并发、高吞吐、性能很高,支持集群化、高可用部署架构、消息高可靠,同时有非常完善便捷的后台管理界面可以使用。但RabbitMQ本身是基于erlang语言开发的,分析源码比较困难。

RocketMQ:阿里开源的,经过阿里的生产环境的超高并发、高吞吐的考验,性能卓越,同时支持分布式事务等特殊场景,基于Java语言开发的,适合阅读源码。

Kafka:超高吞吐量的实时日志采集、实时数据同步、实时数据计算。因此Kafka在大多数领域中配合实时计算基数使用的较多。但是在传统的MQ中间件使用场景中较少采用。

为什么选择rabbitmq?

支持高并发,高吞吐,消息可靠,高可用架构部署,分析源码简单。

AMQP协议是什么?

Advanced Message Queuing Protocol 高级消息队列协议

d96433f56b0140f79452023bc00e41ec.png

RabbitMQ怎么保证消息100%投递成功?

  • 保证消息成功发送

  • 保证MQ节点成功接收

  • 保证MQ节点确认应答

  • 消息补偿机制

  • 保障消息成功投递给MQ中间件

发完消息MQ宕机数据没有了怎么办?

消息持久化

RabbitMQ发消息的时候有个durable参数可以设置,true,就会持久化。就会将内存中的数据更新到磁盘。即使MQ 宕机了磁盘中也有数据。

6d3870f3366b3b7264ca05b3a52d2b05.png

Confirm机制

什么时候持久化成功不知道,rabbitmq回调机制通知我们是否持久化成功(ack/nack)

4fa20210db2569557fc078cf79c6b9a0.png

如果都是一条一条更新磁盘太耗费性能了,所以MQ持久化磁盘是等到几千条消息统一刷到磁盘上。 

但是还没有刷盘到磁盘MQ就宕机了怎么办?

消息提前持久化+定时任务

0012477e7d86f9646d3c10a741da5bc6.png

如何解决数据丢失的问题?

持久化(上面)

RabbitMQ是如何解决消息重复消费的问题的?

幂等性问题解决

1.乐观锁

update 表 set count= count + 1 and version = version + 1

where version = 1 (库存服务表的version)

首先查询版本号然后再操作时带上版本号,第一次调用库存服务version = 1,调用一次库存服务version= version+ 1 =2,返回订单服务失败,订单服务再次调用传入版本号为1,但是此时库存服务的version已经等于2了所以不会执行上面的sql语句。

2.唯一ID+指纹码

select count(1) 表 where id = 唯一id+指纹码

执行完了返回大于0 的数据说明操作过。结果为0表示没有操作过。

3.Redis原子操作

数据库和redis要么一起成功要么一起失败。

RabbitMQ如何保证消息队列的顺序性?

例如发送订单,支付必须保证顺序,可以结合自己的项目进行封装

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/716836
推荐阅读
相关标签
  

闽ICP备14008679号