RabbitMQ学习(一)

rabbitmq 由四部分:

生产者,消息队列,消费者是最重要的三个概念,生产者发消息到消息队列中去,消费者监听指定的消息队列,并且当消息队列收到消息之后,接收消息队列传来的消息,并且给予相应的处理.

RabbitMQ来说,除了这三个基本模块以外,还添加了一个模块,即交换机(Exchange).它使得生产者和消息队列之间产生了隔离,生产者将消息发送给交换机,而交换机则根据调度策略把相应的消息转发给对应的消息队列.

交换机有四种类型,分别为Direct,topic,headers,Fanout.

Direct是RabbitMQ默认的交换机模式,也是最简单的模式.即创建消息队列的时候,指定一个BindingKey.当发送者发送消息的时候,指定对应的Key.当Key和消息队列的BindingKey一致的时候,消息将会被发送到该消息队列中.

  topic转发信息主要是依据通配符,队列和交换机的绑定主要是依据一种模式(通配符+字符串),而当发送消息的时候,只有指定的Key和该模式相匹配的时候,消息才会被发送到该消息队列中.

  headers也是根据一个规则进行匹配,在消息队列和交换机绑定的时候会指定一组键值对规则,而发送消息的时候也会指定一组键值对规则,当两组键值对规则相匹配的时候,消息会被发送到匹配的消息队列中.

  Fanout是路由广播的形式,将会把消息发给绑定它的全部队列,即便设置了key,也会被忽略.

1、安装

☐ 2、springboot整合rabbitmq

☐ 3、direct

☐ 4、topic

☐ 5、headers

☐ 6、fanout

原来想按照步骤一步一步来进行熟悉和学习,但是当开始想整合springboot和rabbitmq的时候,发现例子中用的方法都不知道是什么这么写,跟个傻子一样照抄代码,这不是我想要的学习。所以找了书,从头开始学习rabbitmq,理解它的框架、协议、原理,然后才进行编码,这样才有底气去写东西,才知道自己写的究竟是什么。

今天就先来整理一下这几天学习的rabbitmq基础的东西。

rabbitmq整体上是一个生产者和消费者模型,主要负责接收、存储和转发消息。这里盗个图:

上图是rabbitmq的模型架构,如果详细来讲各个部分的话,估计需要一本书的长度,我这里就从我理解和记住的东西来说了。

rabbitmq使用erlang语言实现了AMQP(Advanced Message Queuing Protocal,高级消息队列协议)协议,这个协议是什么?这里再盗个图:

rabbitmq就是使用erlang重写和封装了这个协议中的各种命令,然后客户端就可以通过调用rabbitmq的这些方法来使用这个协议进行消息传递。

从上面的模型架构图中可以看到生产者将消息发送给交换器,然后交换器发送到队列中,消费者再从队列中获取消息进行消费,实际上消费者消费完消息后要发送确认命令,然后队列会将消费完的消息从队列中删除。

这个过程当中有几个地方需要注意:

1、消费者要向哪个交换器中发送消息?

2、交换器怎么知道向哪个或哪些队列中放入消息?

3、消费者消费哪个或哪些队列中的消息?

4、若交换器没有找到能放消息的队列要怎么做?

5、队列中的消息一直没有消费者消费要怎么做?

我们先看一段示例代码:

第一个问题:这个是具体的逻辑设计决定的,你想让哪些交换器和队列处理哪些问题可以自己设计处理逻辑的时候决定,这个跟rabbitmq的实现原理没什么关系。

第二个问题:创建交换器的时候指定了交换器的名字,创建队列的时候指定了队列的名字,然后将交换器和队列进行了绑定,通过什么绑定的呢?通过路由键。然后通过指定的交换器和路由键发送消息,就会从指定的交换器上根据指定的路由键找到绑定的队列,然后将消息放入其中。这里一个交换器上可以绑定多个队列,绑定时的路由键可以不同,发送消息时指定的路由键不一定是具体的路由键,可以使正则表达式,然后就可以将消息同时放入符合表达式的队列中。

第三个问题

我们看看消费者的代码:

从代码中可以看到是通过指定队列名字来消费某个队列中的消息的。

至于第四和第五个问题后面再回答,先记录两个过程:

第四个问题:发送消息的方法中有两个参数可以设置:mandatory和immediate,这两个参数都有当消息传递过程中不可达目的地时将消息返还给生产者的功能。

其中mandatory的作用:它针对的是队列,若为true,则当交换器没有路由到可以投递的队列时,将消息返回给生产者;若为false,则当交换器没有路由到可以投递的队列时,将消息直接丢弃。

immediate的作用:它针对的是消费者,若为true,则当交换器将消息路由到队列上时,若队列上没有消费者,则这条消息将不会存入队列中,若与路由键匹配的所有队列上都没有消费者,则将消息返还给生产者。

RabbitMQ3.0取消了对immediate参数的支持。

那么生产者如何获取到返回来的消息呢?通过添加ReturnListener监听器实现。

还可以使用备份交换器,又叫”备胎交换器“,可以将未被路由的消息保存在备份的交换器绑定的队列中,然后需要的时候再去处理。可以通过如下方式声明:

第五个问题:可以通过设置过期时间,过期时间有两种:队列的过期时间和消息的过期时间。

若设置队列的过期时间则队列中的所有消息都有相同的过期时间,若设置消息的过期时间则,每条消息可以有不同的过期时间。若同时设置了队列的过期时间和消息的过期时间则以两者中较小的那个为准。对于第一种设置队列TTL的方法,一旦消息过期就会被从队列中抹去,而第二种设置消息过期时间的方法,即使消息过期也不会马上从队列中抹去,因为每条消息是否过期是在即将投递到消费者之前判定的。至于为什么这么设计呢?这里盗个图:

另外,我们称达到过期时间的消息为DeadMessage(死信),当消息在一个队列之中变成死信之后,它能被重新发送到另一个交换器中,我们称之为死信交换器,与它绑定的队列成为死信队列。

消息什么情况下会变成死信呢?盗个图:

使用方式如下:

相对完整的例子如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值