zoukankan      html  css  js  c++  java
  • 1、RabbitMQ的引入、使用业务场景、优势、工作机制

    1、RabbitMQ介绍及使用场景、优势
    MQ全称为Message Queue,即消息队列,又叫做消息中间件。RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法。通过高效可靠的消息传递机制进行与平台无关的数据交流。基于数据通信来进行分布式系统的集成,通过提供消息传递和消息队列模型,可以在分布式环境下扩展进程的通信。消息队列在分布式系统开发中应用非常广泛。
    RabbitMQ官方地址请移步!
    问题1:使用MQ的业务场景:
    1)可进行异步处理的业务(解决了不需要同步处理,且耗时长消息接收方可以异步处理的业务问题)
    同步的通信:发出一个调用请求之后,在没有得到结果之前,就不返回。由调用者主动等待这个调用的结果。
    异步通信:调用在发出之后,这个调用就直接返回了,所以没有返回结果。也就是说,当一个异步过程调用发出后,调用者不会马上得到结果。而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。
    2)可以对没有依赖关系的业务进行解耦操作(退货操作后,需要恢复库存、资金退还、发送通知,这些业务之间没有相应的依赖关系)
    耦合是系统内部或者系统之间存在相互作用,相互影响和相互依赖。在我们的分布式系统中,一个业务流程涉及多个系统的时候,他们之间就会形成一个依赖关系。
    示列:在传统的通信方式中,订单系统发生了退货的动作,那么要依次调用所有下游系统的 API,比如调用库存系统的 API 恢复库存,因为这张火车票还要释放出去给其他乘客购买;调用支付系统的 API,不论是支付宝微信还是银行卡,要把手续费扣掉以后,原路退回给消费者;调用通知系统 API 通知用户退货成功。这个过程是串行执行的,如果在恢复库存的时候发生了异常,那么后面的代码都不会执行。由于这一系列的动作,恢复库存,资金退还,发送通知,本质上没有一个严格的先后顺序,也没有直接的依赖关系,也就是说,只要用户提交了退货的请求,后面的这些动作都是要完成的。库存有没有恢复成功,不影响资金的退还和发送通知。
    解决方案1:
    使用多线程或者线程池是可以实现的,但是每一个需要并行执行的地方都引入线程,又会带来线程或者线程池的管理问题。
    解决方案2:使用MQ订单系统只需要把退货的消息发送到消息队列上,由各个下游的业务系统自己创建队列,然后监听队列消费消息。在这种情况下订单系统里面就不需要配置其他系统的 IP、端口、接口地址了,因为它不需要关心消费者在网络上的什么位置,所以下游系统改 IP 没有任何影响。甚至不需要关心消费者有没有消费成功,它只需要把消费发到消息队列的服务器上就可以了。这样,我们就实现了系统之间依赖关系的解耦。
    3)实现流量削锋:
    在很多的电商系统里面,有一个瞬间流量达到峰值的情况,比如京东的 618,淘宝的双 11,还有小米抢购。普通的硬件服务器肯定支撑不了这种百万或者千万级别的并发量。如果通过堆硬件的方式去解决,那么在流量峰值过去以后就会出现巨大的资源浪费。那要怎么办呢?如果说要保护我们的应用服务器和数据库,限流也是可以的,但是这样又会导致订单的丢失,没有达到我们的目的。引入MQ,MQ是队列,一定有队列的特性,(先进先出)就可以先把所有的流量承接下来,转换成 MQ 消息发送到消息队列服务器上,业务层就可以根据自己的消费速率去处理这些消息,处理之后再返回结果。
    对上述1~3的总结:
    a.对于数据量大或者处理耗时长的操作,我们可以引入 MQ 实现异步通信,减少客户端的等待,提升响应速度(如:日志记录)。
    b.对于改动影响大的系统之间,可以引入 MQ 实现解耦,减少系统之间的直接依赖(如:订单取消后增加库存、退还支付金额、发送消息通知)。
    c.对于会出现瞬间的流量峰值的系统,我们可以引入 MQ 实现流量削峰,达到保护应用和数据库的目的(如:商品抢购预定)。

    问题2:市场上还有哪些消息队列?
    ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ、Redis。

    问题3:为什么选择使用RabbitMQ呢?
    1)使得简单,功能强大。
    2)基于AMQP协议:除了Qpid,RabbitMQ是唯一一个实现了AMQP标准的消息服务器;
    3)可靠性:RabbitMQ的持久化支持,保证了消息的稳定性;
    4)集群部署简单:正是应为Erlang使得RabbitMQ集群部署变的超级简单;
    5)社区活跃,文档完善,根据网上资料来看,RabbitMQ也是首选;
    6)高并发性能好,RabbitMQ使用了Erlang开发语言,Erlang是为电话交换机开发的语言,天生自带高并发光环,和高可用特性;
    5)Spring Boot默认已集成RabbitMQ
    2、RabbitMQ的工作机制
    2.1 要了解RabbitMQ的工作机制,需要清楚以下八个概念:
    1)Broker(英文含义:代理、中间人,这里成为消息队列服务):,此进程包括两个部分:Exchange和Queue。
    a.Exchange :消息队列交换机,按一定的规则将消息路由转发到某个队列,对消息进行过虑。队列使用绑定键(Binding Key)跟交换机建立绑定关系。
    b.Queue :消息队列,存储消息的队列,消息到达队列并转发给指定的消费方,它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。
    2)Producer(消息生产者):即生产方客户端,生产方客户端将消息发送到MQ。
    3)Consumer(消息消费者):即消费方客户端,接收MQ转发的消息。
    4)Message(消息):消息是不具名的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。
    5)Binding(绑定):用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。
    6)Connection(连接):无论是生产者发送消息,还是消费者接收消息,都必须跟Broker之间建立一个连接,这个是TCP长连接
    7)Channel(信道):多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内的虚拟连接,AMQP 命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为对于操作系统来说建立和销毁 TCP 都是非常昂贵的开销,所以引入了信道的概念,用以复用一条 TCP 连接。
    "信道"是建立在"连接"基础上的,实际开发中"连接"应为全局变量,"信道"为线程级。一个连接(Connections)可以创建多个信道【采用多线程】;一个应用或者一个线程都是一个信道,在信道中 创建队列Queue。生产者的信道一般会立马关闭;消费者是一直侦听的,信道几乎是会一直存在。
    8)Virtual Host:虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。
    每个Rabbit都能创建很多vhost,我们称之为虚拟主机,每个虚拟主机其实都是mini版的RabbitMQ,拥有自己的队列,交换器和绑定,拥有自己的权限机制。vhost是AMQP概念的基础,必须在连接时指定,每一个RabbitMQ服务器都有一个默认的虚拟主机“/”。RabbitMQ server可以说就是一个消息队列服务器实体(Broker),Broker当中可以有多个用户,而用户只能在虚拟主机的粒度进行权限控制,所以RabbitMQ中需要多个虚拟主机。vhost的特性如下:
    a.RabbitMQ默认的vhost是“/”开箱即用;
    b.多个vhost是隔离的,多个vhost无法通讯,并且不用担心命名冲突(队列、交换器、绑定),实现了多层分离;
    c.创建用户的时候必须指定vhost
    2.2 RabbitMQ消息创建、订阅、消费过程原理:
    创建TCP连接--TCP连接认证并创建信道--消息投递到交换机--交换机转发到具体队列--队列再将消息以推送或者拉取方式给消费者进行消费
    a.应用程序和Rabbit Server之间会创建一个TCP连接,一旦TCP打开,并通过了认证(认证就是你试图连接Rabbit之前发送的Rabbit服务器连接信息和用户名和密码,有点像程序连接数据库),应用程序就Rabbit就创建了一条AMQP(Advanced Message Queue 高级消息队列协议)信道,该信道是创建在“真实”TCP上的虚拟连接,AMQP命令都是通过信道发送出去的,每个信道都会有一个唯一的ID,不论是发布消息,订阅队列或者介绍消息都是通过信道来完成的。
    b.生产者发送消息不会像传统方式直接将消息投递到队列中,而是先将消息投递到交换机中,在由交换机转发到具体的队列,队列再将消息以推送或者拉取方式给消费者进行消费。交换机的作用根据具体的路由策略分发到不同的队列中。(这是交换机的作用)

    问题1:为什么不通过TCP直接发送命令?
    对于操作系统来说创建和销毁TCP会话是非常昂贵的开销,假设高峰期每秒有成千上万条连接,每个连接都要创建一条TCP会话,这就造成了TCP连接的巨大浪费,而且操作系统每秒能创建的TCP也是有限的,因此很快就会遇到系统瓶颈。如果我们每个请求都使用一条TCP连接,既满足了性能的需要,又能确保每个连接的私密性,这就是引入信道概念的原因。
    3、erLong9.3 与 rabbitmq 3.7.5中的常用命令:
    1)安装、启动、停止命令:
    ##安装服务
    rabbitmq-service.bat install
    ##停止服务
    rabbitmq-service.bat stop
    ##启动服务
    rabbitmq-service.bat start
    2)对虚拟主机的相关命令操作:
    ##通过rabbitmqctl工具命令创建
    rabbitmqctl add_vhost[vhost_name]
    ##删除vhost
    rabbitmqctl delete_vhost[vhost_name]
    ##查看所有的vhost
    rabbitmqctl list_vhosts
    参看文章
    https://www.cnblogs.com/Jeely/p/12388913.html 如何安装
    https://blog.csdn.net/weixin_44015043/article/details/104861596 下载安装
    http://erlang.org/download/otp_win64_20.3.exe erlang 20.3下载
    https://www.rabbitmq.com/which-erlang.html erlang 与 rabbitmq对应的版本信息
     
  • 相关阅读:
    全新通用编程语言 Def 招募核心贡献者、文档作者、布道师 deflang.org
    全球最快的JS模板引擎:tppl
    4行代码实现js模板引擎
    [Node.js框架] 为什么要开发 Codekart 框架
    Android用BusyBox替换系统toolbox
    纪念一下,昨天换手机了
    在Android上使用gcc编译C/C++源程序
    关于BAPI_ACC_DOCUMENT_POST解读
    关于ABAP和JSON互相转换
    关于客户和供应商预制凭证添加WBS字段
  • 原文地址:https://www.cnblogs.com/jiarui-zjb/p/14312598.html
Copyright © 2011-2022 走看看