1. 什么是rabbitmq?
RabbitMQ是由Erlang语言编写的实现了高级消息队列协议(AMQP)的开源消息代理软件。Erlang语言在数据交互方面性能优秀,有着和原生Socket一样的延迟。
RabbitMQ 是一个
面向消息的中间件
,我给中间件的定义,它是一个软件与软件间进行通信的桥梁。比如,我用微信撩妹儿,那么,微信这个软件它就是一个中间件,我和妹子它就是一个软件的角色了。
2. 为什么使用mq?
-
首先来看一个业务场景
image.png
- 假设现在我们开发一个微服务项目,有三个模块,分别是订单、商品、支付模块。
- 当用户进行下单操作的时候,需要调用商品服务进行扣库存服务。订单服务等待商品服务的返回。
- 当商品服务正常响应给订单服务的时候,再调用支付服务进行支付,支付服务可能对接银行等操作,订单服务继续等待支付服务返回,一切流程走完,下单成功。
- 不难看出,上方这个业务,存在的问题还是挺多的。比如
- 整条链路的操作都是同步的,用户等待时间可能过长。
- 服务间的耦合度过高,上游服务非常依赖下游服务,无论是商品还是支付等服务,只要有一方操作失败,那么就下单失败了。
- 没有缓冲区,在并发场景下,大量的请求阻塞,导致服务异常等等情况。
- 基于异步线程的优化方案。如图
image.png
当请求进行时候,利用线程池创建新的线程来处理请求,主线程直接返回。这种方式确实解决了用户等待的问题,但可能会导致线程大量堆积、cpu升高,甚至某个线程莫名其妙被kill掉了。
-
关于以上的全部问题,来看看mq的处理方式
image.png 解决的问题
- 降低个模块间松耦,上游和下游通过中间件进行通信。
- 增加了缓冲区,比如支付服务出现了问题,订单服务发出去的支付消息会被存放在rabbitmq的队列里,如支付服务恢复了,再从指定的队列里拿到消息消费即可。
- 削峰填谷等。
3. 再看amqp协议
image.png
协议
,也是一种约定,就好像爸妈管教小孩,学完习再看电视、规定睡觉时间。而amqp协议,则定义了rabbitmq内部的结构和外部的行为。个名词解释:
- Broker: RabbitMQ Server就是Message Broker。
- Virtual host: 虚拟主机。可以划分出多个vhost,每个用户在自己的vhost创建exchange/queue(不同vhost下可以同名)等。类似于网络中的namespace概念。
- Connection: publisher/consumer和broker之间的物理(TCP)连接。断开连接的操作只会在client端进行,Broker不会断开连接,除非出现网络故障或broker服务出现问题。
- Channel: 通道。如果每一次访问RabbitMQ都建立一个Connection,在消息量大的时候建立TCP Connection的开销将是巨大的,效率也较低。Channel是在connection内部建立的逻辑连接,如果应用程序支持多线程,通常每个thread创建单独的channel进行通讯,AMQP method包含了channel id帮助客户端和message broker识别channel,所以channel之间是完全隔离的。Channel作为轻量级的Connection极大减少了操作系统建立TCP connection的开销。
- Exchange: 交换机。message到达broker的第一站,然后再根据分发规则以及routing key,分发消息到queue中去。交换机常用的类型有:direct (point-to-point), topic (publish-subscribe) and fanout (multicast)。
- Queue: 消息最终被送到这里等待consumer取走。一个message可以被同时拷贝到多个queue中。
- Binding: exchange和queue之间的虚拟连接,binding中可以包含routing key。Binding信息被保存到exchange中的查询表中,用于message的分发依据。