消息中间件之RabbitMq

消息中间件是系统间异步交互的重要手段之一,目前常用的消息中间件很多,包括Rabbitmq、Activemq、Rocketmq、IBM MQ、kafka等,这些都是成熟的技术体系,理论上,只要是可以存储数据的软件,都可用来做消息中间件,比如redis,再比如各种数据库,当然软件设计都有其定位,我们也没必要做舍本求末的事情。

下面主要说其中的RabbitMq

RabbitMq是用Erlang语言编写的实现了高级消息队列协议(AMQP:Advanced Message Queue Protocol)的开源的消息中间件。

主要概念介绍

publisher:发布者,也可以称producer生产者,负责推送消息到rabbitmq;

consumer:消费者,负责从rabbitmq消费消息;

vhost:虚拟机,一个rabbitmq进程可以有多个vhost,每个vhost互相隔离,可以单独配置权限,类似mysql中得多个schema;

queue:消息队列,具体存放消息的盒子;

exchange:交换机,producer发消息到rabbitmq不是直接发到queue的,而是通过exchange根据相应的规则路由到queue的;

bindingkey:exchange和queue的绑定关系叫bindingkey,一个exchange可以绑定多个queue(bindingkey可以相同也可以不同),一个queue也可以绑定到多个exchange(bindingkey可以相同也可以不同);

routingkey:producer发送消息到exchange,并指定routingkey,那么exchange就会把消息路由给bindingkey和routingkey能对应上的所有queue中(rabbitmq有多种exchange类型,不是都靠routingkey和bindingkey进行匹配路由的,后面会详细介绍);

其简单模型图如下:

消息中间件之RabbitMq_第1张图片

交换机(exchange)详细介绍

RabbitMq交换机主要有四种,每一种交换机都有自己的路由规则:

直连交换机(Direct Exchange)

该交换机的作用简单明了,就是将发送过来的消息,根据其指定的routingkey去匹配bindingkey,匹配上了(routingkey=bindingkey)就将消息发送到对应的queue中,如下图所示,一个routingkey="key_a"的消息就会路由到queue01和queue02。

 

消息中间件之RabbitMq_第2张图片

 

扇形交换机(Fanout Exchange)

扇形交换机会将消息路由到绑定在其上的所有队列中,它不会去匹配routingkey和bindingkey,它是一个广播路由,下图中只要有消息发到该交换机,那么queue01、queue02、queue03都会收到消息。

消息中间件之RabbitMq_第3张图片

主题交换机(Topic Exchange)

主题交换机跟上面说的直连交换机很相似,也是通过routingkey和bindingkey匹配路由消息的,不同点在于,直连交换机的匹配规则是routingkey=bindingkey,而主题交换机的匹配规则可以理解成routingkey like '%bindingkey%',也就是说主题交换机是模糊匹配,其具体匹配规则如下:

routingkey的定义跟java包的定义类似用"."分隔单词,如user.log.info;

bindingkey的定义也是"."分隔,但是它可以拥有两个通配符,一个为"*",匹配一个单词,一个为"#",匹配零或多个单词;

如下图所示,routingkey="user.log.info"的消息可以路由到queue02和queue03;routingkey="process.log.error"的消息可以路由到queue01和queue03;routingkey="user.request.log"的消息可以路由到queue02。

消息中间件之RabbitMq_第4张图片

 

头交换机(Headers Exchange)

头交换机的路由规则不依赖于routingkey和bindingkey的匹配关系,而是一种特殊的键值对匹配规则,具体规则为:

队列queue和交换机exchange也有绑定关系,但是不叫bindingkey,而是通过一组键值对来绑定,其中有两个特殊的参数:

x-match:any,表示当前组内键值对只要有一个能匹配到,消息就可以进来;

x-match:all,表示当前组内键值对必须全部匹配,消息才能进来;

publisher在发布消息时必须指定消息头,头交换机就会根据消息的消息头来做路由匹配,例如:有一个消息头为name:beijing的消息,可以路由到queue01;消息头为name:shanghai,id:123的消息可以路由到queue01和queue02;消息头为id:123的消息可以路由到queue01。

消息中间件之RabbitMq_第5张图片

RabbitMq消息可靠性

1、RabbitMq可以分为磁盘节点和内存节点

内存节点:exchange、queue、vhost等元数据信息系都存在内存中,当然消息本身也只会在内存中,当服务器宕机重启,将丢失所有的信息;

磁盘节点:元数据和消息都会持久化到磁盘,服务器宕机重启可以自动恢复;

单机RabbitMq只能是磁盘节点,保证服务器宕机重启后可以恢复数据;而在集群模式中,一般至少会保证有两个磁盘节点和多个内存节点,既保证了数据的可靠性,又保证了服务器的性能。

2、数据发送到consumer后,消息会从队列中移除,但是这个移除动作不是立马完成,而是需要consumer ack后,默认情况下是自动ack,消息给到consumer就删除,但是如果consumer处理消息失败,消息就丢失了,所以如果消息很重要,也可以手动设置ack,确认消息处理成功后通知rabbitmq删除该消息。

你可能感兴趣的:(rabbitmq,交换机)