任务队列和消息队列:本质都是队列,所以就只举一个任务队列的例子 。假设这个饭店在高峰期顾客很多,而厨师只有很少的几个,所以服务员们不得不把单子按下单顺序放在厨房的桌子上,供厨师们一个一个做,这一堆单子就是任务队列,厨师们每做完一个菜,就从桌子上的订单里再取出一个单子继续做菜 。
角色分担如下图:
文章插图
图 11:RabbitMQ 在 RPC 中角色
使用 RabbitMQ 的好处:
- 同步变异步:可以使用线程池将同步变成异步,但是缺点是要自己实现线程池,并且强耦合 。使用消息队列可以轻松将同步请求变成异步请求 。
- 低内聚高耦合:解耦,减少强依赖 。
- 流量削峰:通过消息队列设置请求最大值,超过阀值的抛弃或者转到错误界面 。
- 网络通信性能提高:TCP 的创建和销毁开销大,创建 3 次握手,销毁 4 次分手,高峰时成千上万条的链接会造成资源的巨大浪费,而且操作系统每秒处理 TCP 的数量也是有数量限制的,必定造成性能瓶颈 。
一条 TCP 连接可以容纳无限条信道(硬盘容量足够的话),不会造成性能瓶颈 。
RabbitMQ 的三种类型的交换器
RabbitMQ 使用 Exchange(交换机)和 Queue(队列)来实现消息队列 。
在 RabbitMQ 中一共有三种交换机类型,每一种交换机类型都有很鲜明的特征 。
基于这三种交换机类型,OpenStack 完成两种 RPC 的调用方式 。首先简单介绍三种交换机 。
文章插图
图 12:RabbitMQ 架构图
①广播式交换器类型(Fanout)
该类交换器不分析所接收到消息中的 Routing Key,默认将消息转发到所有与该交换器绑定的队列中去 。
文章插图
图 13:广播式交换机
②直接式交换器类型(Direct)
该类交换器需要精确匹配 Routing Key 与 Binding Key,如消息的 Routing Key = Cloud,那么该条消息只能被转发至 Binding Key = Cloud 的消息队列中去 。
文章插图
图 14:直接式交换机
③主题式交换器(Topic Exchange)
该类交换器通过消息的 Routing Key 与 Binding Key 的模式匹配,将消息转发至所有符合绑定规则的队列中 。
Binding Key 支持通配符,其中“*”匹配一个词组,“#”匹配多个词组(包括零个) 。
文章插图
图 15:主题式交换机
注:以上四张图片来自博客园,如有侵权,请联系作者:https://www.cnblogs.com/dwlsxj/p/RabbitMQ.html 。
当生产者发送消息 Routing Key=F.C.E 的时候,这时候只满足 Queue1,所以会被路由到 Queue 中 。
如果 Routing Key=A.C.E 这时候会被同时路由到 Queue1 和 Queue2 中,如果 Routing Key=A.F.B 时,这里只会发送一条消息到 Queue2 中 。
Nova 基于 RabbitMQ 实现两种 RPC 调用:
- RPC.CALL(调用)
- RPC.CAST(通知)
RPC.CALL
RPC.CALL 是一种双向通信流程,即 RabbitMQ 接收消息生产者生成的系统请求消息,消息消费者经过处理之后将系统相应结果反馈给调用程序 。
文章插图
图 16:RPC.CALL 原理图
一个用户通过 Dashboard 创建一个虚拟机,界面经过消息封装后发送给 NOVA-API 。
NOVA-API 作为消息生产者,将该消息以 RPC.CALL 方式通过 Topic 交换器转发至消息队列 。
此时,Nova-Compute 作为消息消费者,接收该信息并通过底层虚拟化软件执行相应虚拟机的启动进程 。
待用户虚拟机成功启动之后,Nova-Compute 作为消息生产者通过 Direct 交换器和响应的消息队列将虚拟机启动成功响应消息反馈给 Nova-API 。
此时 Nova-API 作为消息消费者接收该消息并通知用户虚拟机启动成功 。
推荐阅读
- 程序员=青春饭”?不,程序员是一个具备长久生命力的职业
- 中药枕头哪种好
- |您以为钓鱼是“娱乐”?有时候它还是一个“悲伤”的故事
- 梦见收养了一个孩子表示什么 做梦梦见收养了一个女儿
- 红薯腊八粥
- 梦见一个钩上有很多鱼 梦见钩了很多鱼
- 在一个千万级的数据库查寻中,如何提高查询效率?
- 一个男人一旦提出离婚 男人比女人更害怕离婚
- 松茸蒸蛋羹
- 睡了一个比自己小9岁的男人靠谱吗,姐弟恋对女人生理好不好