Rabbit MQ 介绍
- RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,起初源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗.RabbitMQ主要是为了实现系统之间的双向解耦而实现的.当生产者大量生产数据时,消费者无法快速消费,就需要一个中间层,保存这个数据.
- AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计.消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然.AMQP的主要特征是面向消息、队列、路由(包括点对点&发布/订阅)、可靠性、安全.
- RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX.用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗.
相关概念
通常我们谈到队列服务,会有一个流程概念:提供者->队列->消费者,RabbitMQ在这个基本概念上,多做了一层抽象,在发消息者和队列之间,加入了交换器(Exchange).这样发消息者和队列就没有没有直接联系,转而变成消息提供者把消息交给交换器,交换器根据调度策略再把消息交给队列.
虚拟主机:
- 一个虚拟主机持有一组交换机、队列和绑定.为什么需要多个虚拟主机呢?很简单,RabbitMQ当中,用户只能在虚拟主机粒度进行权限控制.因此,如果需要禁止A组访问B组的交换机/队列/绑定,必须为A和B分别创建一个虚拟主机.每一个RabbitMQ服务器都会有一个默认的虚拟主机"/".
交换机:
- Exchange用于转发消息,但是它不会做存储,如果没有Queue bind到Exchange的话,他会直接丢弃掉Producer发送过来的消息.这里有一个比较重要的概念:路由键.消息到交换机的时候,交换机会转发到对应的队列中,那么究竟转发到哪个队列,就要根据该路由键.
绑定:
- 也就是交换机需要和队列相绑定,这其中是多对多关系.
交换机:
交换机的功能主要是接受消息并且转发到绑定的队列,交换机不存储消息,在启用ack模式后,交换机找不到队列会返回错误.交换机有四种类型:Driect,Topic,Headers,Fanout
Direct: "先匹配,再投送",即在绑定时设定一个routing_key,消息的routing_key匹配时,才会被交换器投送到绑定的队列去.
Topic: 按规则转发消息(最灵活)
Headers: 设置header attribute参数类型的交换机
Fanout: 转发消息到所有绑定队列.
Direct Exchange
Direct Exchange 是RabbitMQ默认的交换机模式,也是最简单的模式,根据key全文匹配去寻找队列.
第一个X-Q1就有一个binding key,名字为orange;X-Q2有两个binding key,名字为black和green.当消息中的路由键和这个binding key对应上的时候,就知道该消息去到哪个队列中.
Topic Exchange
Topic Exchange转发消息主要是根据通配符.在这种交换器下,队列和交换机的绑定会定义一种路由模式,那么,通配符就要在这种路由模式和路由键之间匹配后交换器才能转发消息.
在这种交换机模式下:
路由键必须是一串字符,用句号(.)隔开,比如说agreements.us,或者agreements.us.stockholm等.
路由模式必须包含一个星号()或者井号(#),()主要用于匹配路由键指定位置的一个单词,(#)主要用于匹配指定位置的0个或多个单词.
消息发送代码示例如下:
rabbitTemplate.convertAndSend("testTopicExchange","key1.a.c.key2","this is Rabbit")
Param1表示交换器,Param2表示路由键,Param3表示消息.
Headers Exchange
headers也是根据规则匹配,相较于direct和topic固定地使用routing_key,headers是一个使用自定义匹配规则的类型,在队列与交换器绑定时,会设定一组键值对规则,消息中也包括一组键值对(headers)属性,当这些键值对有一对,或全部配对时,消息被投送到对应队列.
Fanout Exchange
Fanout Exchange消息广播的模式,不管路由键或者是路由模式,会把消息发给绑定它的全部队列,如果配置了routingkey会被忽略.