rabbitmq学习

Posted by Xsp on December 15, 2018

Rabbitmq知识点

主要参考:http://wiki.jikexueyuan.com/project/rabbitmq/hello-world.html

启动后可以打开:http://127.0.0.1:15672/ 登录查看

交换机(Exchanges)

RabbitMQ 消息模型的核心理念是:发布者(producer)不会直接发送任何消息给队列。事实上,发布者(producer)甚至不知道消息是否已经被投递到队列。

发布者(producer)只需要把消息发送给一个交换机(exchange)。交换机非常简单,它一边从发布者方接收消息,一边把消息推送到队列。交换机必须知道如何处理它接收到的消息,是应该推送到指定的队列还是是多个队列,或者是直接忽略消息。这些规则是通过交换机类型(exchange type)来定义的。

2018-12-15-rabbitmq-1.png

可供选择的交换机类型:

  • 直连交换机(direct)
  • 主题交换机(topic)
  • 头交换机(headers):满足对应key-value信息。
  • 扇型交换机(fanout):把消息发送给它所知道的所有队列(广播)。

执行以下命令可以列出所有交换机列表:

$ rabbitmqctl list_exchanges

列表中有一些叫做 amq.* 的交换器,都是默认创建的。

空字符串(“”)代表默认或者匿名交换机:消息将会根据指定的 routing_key 分发到指定的队列。

绑定(Bindings)

2018-12-15-rabbitmq-2.png

交换机和队列之间的联系我们称之为绑定(binding)。告诉交换机如何发送消息给我们的队列。

以下命令会列出所有绑定列表:

$ rabbitmqctl list_bindings 

路由(Routing)

绑定(binding)是指交换机(exchange)和队列(queue)的关系。可以简单理解为:这个队列(queue)对这个交换机(exchange)的消息感兴趣。

绑定的时候可以带上一个额外的 routing_key 参数。绑定键的意义取决于交换机(exchange)的类型。我们之前使用过的扇型交换机(fanout exchanges)会忽略这个值。

直连交换机(Direct exchange)

交换机将会对绑定键(binding key)和路由键(routing key)进行精确匹配,从而确定消息该分发到哪个队列。

2018-12-15-rabbitmq-3.png

在这个场景中,我们可以看到直连交换机 X 和两个队列进行了绑定。第一个队列使用 orange 作为绑定键,第二个队列有两个绑定,一个使用 black 作为绑定键,另外一个使用 green。

这样以来,当路由键为 orange 的消息发布到交换机,就会被路由到队列 Q1。路由键为 black 或者 green 的消息就会路由到 Q2。其他的所有消息都将会被丢弃。

多个绑定(Multiple bindings)

2018-12-15-rabbitmq-4.png

多个队列使用相同的绑定键是合法的。这个例子中,我们可以添加一个 X 和 Q1 之间的绑定,使用 black 绑定键。这样一来,直连交换机就和扇型交换机的行为一样,会将消息广播到所有匹配的队列。带有 black 路由键的消息会同时发送到 Q1 和 Q2。

主题交换机

发送到主题交换机(topic exchange)的消息不可以携带随意什么样子的路由键(routing_key),它的路由键必须是一个由.分隔开的词语列表。这些单词随便是什么都可以,但是最好是跟携带它们的消息有关系的词汇。以下是几个推荐的例子:”stock.usd.nyse”, “nyse.vmw”, “quick.orange.rabbit”。词语的个数可以随意,但是不要超过 255 字节。

绑定键也必须拥有同样的格式。主题交换机背后的逻辑跟直连交换机很相似 —— 一个携带着特定路由键的消息会被主题交换机投递给绑定键与之想匹配的队列。但是它的绑定键和路由键有两个特殊应用方式:

  • * (星号) 用来表示一个单词
  • # (井号) 用来表示任意数量(零个或多个)单词

2018-12-15-rabbitmq-5.png

这个例子里,我们发送的所有消息都是用来描述小动物的。发送的消息所携带的路由键是由三个单词所组成的,这三个单词被两个.分割开。路由键里的第一个单词描述的是动物的手脚的利索程度,第二个单词是动物的颜色,第三个是动物的种类。

我们创建了三个绑定:Q1 的绑定键为 *.orange.*,Q2 的绑定键为 *.*.rabbit 和 lazy.# 。

这三个绑定键被可以总结为:

  • Q1 对所有的桔黄色动物都感兴趣。
  • Q2 则是对所有的兔子和所有懒惰的动物感兴趣。

一个携带有 quick.orange.rabbit 的消息将会被分别投递给这两个队列。携带着 lazy.orange.elephant 的消息同样也会给两个队列都投递过去。另一方面携带有 quick.orange.fox 的消息会投递给第一个队列,携带有 lazy.brown.fox 的消息会投递给第二个队列。携带有 lazy.pink.rabbit 的消息只会被投递给第二个队列一次,即使它同时匹配第二个队列的两个绑定。携带着 quick.brown.fox 的消息不会投递给任何一个队列。

如果我们违反约定,发送了一个携带有一个单词或者四个单词(”orange” or “quick.orange.male.rabbit”)的消息时,发送的消息不会投递给任何一个队列,而且会丢失掉。

但是另一方面,即使 “lazy.orange.male.rabbit” 有四个单词,他还是会匹配最后一个绑定(lazy.#),并且被投递到第二个队列中。

主题交换机是很强大的,它可以表现出跟其他交换机类似的行为:

  • 当一个队列的绑定键为 “#”(井号) 的时候,这个队列将会无视消息的路由键,接收所有的消息。

  • 当 * (星号) 和 # (井号) 这两个特殊字符都未在绑定键中出现的时候,此时主题交换机就拥有的直连交换机的行为。

Spring boot集成rabbitmq

安装并启动rabbitmq

$ rabbitmq-server

从 https://start.spring.io/ 下载初始化项目

添加pom依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

amqp是消息队列标准的一个协议,rabbitmq实现了这个协议。

配置properties文件

# rabbitmq
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

# rabbitmq服务器可以虚拟出多个服务器,每个服务器之间相互独立
# 默认访问 "/" .
# 访问其他的路径需要权限
spring.rabbitmq.virtual-host=/
# 消费者个数
# 监听者的并发数
spring.rabbitmq.listener.simple.concurrency=10
spring.rabbitmq.listener.simple.max-concurrency=10
# 每次取几个
# 每次多取几个消费的快一些。
# 但是取的太多长时间不消费,会导致消息得不到处理
spring.rabbitmq.listener.simple.prefetch=1
# 默认消费者 自动启动
spring.rabbitmq.listener.direct.auto-startup=true
# 消费者 消费失败 则入队重试
spring.rabbitmq.listener.simple.default-requeue-rejected=true
# 生产者
# 队列满了,发不进去,重试
spring.rabbitmq.template.retry.enabled=true
# 重试间隔1000ms
spring.rabbitmq.template.retry.initial-interval=1000ms
# 最大重试 3 次
spring.rabbitmq.template.retry.max-attempts=1
spring.rabbitmq.template.retry.max-interval=10000ms
# 第一次重试间隔1s, 第2次就是 2s, 第3次就是4s
spring.rabbitmq.template.retry.multiplier=2.0

更多配置可以参看:

  • https://docs.spring.io/spring-boot/docs/

  • https://docs.spring.io/spring-boot/docs/2.0.x/reference/htmlsingle/

需要注意:上述配置文件中 guest用户默认只有访问本地服务器的权限,如果rabbitmq-server是远程服务器,需要修改一下 配置文件rabbitmq.config(配置文件可能没有,在rabbitmq根目录的etc目录):

[{rabbit, [{loopback_users, []}]}].

参考:

  • https://www.rabbitmq.com/configure.html
  • https://www.rabbitmq.com/access-control.html

spring boot rabbitmq demo:https://github.com/husterxsp/rabbitmq-demo