赞
踩
模拟两个服务:demo(消息发送)、intr(消息接收)
依赖和配置yml两个服务都需要配置
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
spring: #配置rabbitMq rabbitmq: host: 127.0.0.1 port: 5672 username: guest password: guest
方式一:在RabbitMQ页面添加队列
方式二:在消费者服务定义增加配置类
启动demo和intr服务,在demo服务调用发送消息方法,intr服务日志可看到以下信息:
工作队列(又称:任务队列——Task Queues)是为了避免等待一些占用大量资源、时间的操作。当我们把任务(Task)当作消息发送到队列中,一个运行在后台的工作者(worker)进程就会取出任务然后处理。当你运行多个工作者(workers),任务就会在它们之间共享。
简单来说就是让多个消费者绑定到一个队列,共同消费队列中的消息。
Work模型的使用:
多个消费者绑定到一个队列,同一条消息只会被一个消费者处理
通过设置prefetch来控制消费者预取的消息数量
依赖和配置同上(简单模式),定义队列同上
模拟多个消费者绑定同一个队列,为了简单,这里演示两个消费者放在同一个方法里
可以看出,消息是平均分配给每个消费者,并没有考虑到消费者的处理能力。
消费者配置文件,增加如下配置
spring: rabbitmq: listener: simple: prefetch: 1 # 每次只能获取一条消息,处理完成才能获取下一个消息
测试结果如下:
可以看到,在订阅模型中,多了一个exchange角色,而且过程略有变化:
Publisher:生产者,也就是要发送消息的程序,但是不再发送到队列中,而是发给X(交换机)
Exchange:交换机,图中的X。一方面,接收生产者发送的消息。另一方面,知道如何处理消息,例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作,取决于Exchange的类型。Exchange有以下3种类型:
Fanout:广播,将消息交给所有绑定到交换机的队列
Direct:定向,把消息交给符合指定routing key 的队列
Topic:通配符,把消息交给符合routing pattern(路由模式) 的队列
Exchange(交换机)只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与Exchange绑定,或者没有符合路由规则的队列,那么消息会丢失!
发布订阅模式与之前案例的区别就是允许将同一消息发送给多个消费者。实现方式是加入了exchange(交换机)
在广播模式下,消息发送流程是这样的:
1)可以有多个队列
2)每个队列都要绑定到Exchange(交换机)
3)生产者发送的消息,只能发送到交换机,交换机来决定要发给哪个队列,生产者无法决定
4)交换机把消息发送给绑定过的所有队列
5)订阅队列的消费者都能拿到消息
我们的计划是这样的:
创建一个交换机 exchange.fanout,类型是Fanout
创建两个队列fanout.queue1和fanout.queue2,绑定到交换机exchange.fanout
在消费者服务定义增加配置类
在Direct模型下:
队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key)
消息的发送方在 向 Exchange发送消息时,也必须指定消息的 RoutingKey。
Exchange不再把消息交给每一个绑定的队列,而是根据消息的Routing Key进行判断,只有队列的Routingkey与消息的 Routing key完全一致,才会接收到消息
Direct Exchange 会将接收到的消息根据规则路由到指定的Queue,称为路由模式(routes)
每一个Queue都与Exchange设置一个BindingKey
发布者发送消息时,指定消息的RoutingKey
Exchange将消息路由到BindingKey与消息RoutingKey一致的队列
方式一、基于@Bean的方式
方式二、基于注解方式@RabbitListener上声明,看4.2.2上已声明
Topic类型的Exchange与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key的时候使用通配符!
Routingkey一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert
通配符规则:
#:匹配一个或多个词
*:匹配1个词
举例:
item.#:能够匹配`item.spu.insert` 或者 `item.spu`
item.*:只能匹配`item.spu`
方式一、基于@Bean的方式
方式二、基于注解方式@RabbitListener上声明,看4.3.2上已声明
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。