微服务框架
【SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】
SpringCloud微服务架构
文章目录
- 微服务框架
- SpringCloud微服务架构
- 16 SpringAMQP
- 16.7 DirectExchange
- 16.7.1 发布订阅 - DirectExchange
- 16.7.2 直接开干
- 16.7.3 总结
16 SpringAMQP
16.7 DirectExchange
16.7.1 发布订阅 - DirectExchange
Direct Exchange 会将接收到的消息根据规则路由到指定的Queue,因此称为路由模式(routes)。
- 每一个Queue都与Exchange设置一个BindingKey
这个BindingKey就像是交换机和消息队列之间约定的暗号一样,现在约定好,将来就按照这个暗号进行通信
- 发布者发送消息时,指定消息的RoutingKey
比如现在这个key 为 blue,
- Exchange将消息路由到BindingKey与消息RoutingKey一致的队列【对暗号】
这次消息通信,就只有queue1 接收了
如果再来一个key 为yellow 的消息,就只有queue2 可以接受处理了
【而且】一个队列再和交换机进行绑定关系时,可以指定多个 key
像上面这样,如果说现在恰好来了一个 key 为 red 的消息
这样两个队列都会收到,就达到了广播的效果【对比起来,它有Fanout的 特性,但是它比Fanout 更加灵活】
16.7.2 直接开干
利用SpringAMQP演示DirectExchange的使用
整体架构:
实现思路如下:
-
利用@RabbitListener声明Exchange、Queue、RoutingKey
-
在consumer服务中,编写两个消费者方法,分别监听direct.queue1和direct.queue2
-
在publisher中编写测试方法,向itcast. direct发送消息
步骤1:在consumer服务声明Exchange、Queue
-
在consumer服务中,编写两个消费者方法,分别监听direct.queue1和direct.queue2,
-
并利用@RabbitListener声明Exchange、Queue、RoutingKey
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "direct.queue1"),
exchange = @Exchange(name = "itcast.direct",type = ExchangeTypes.DIRECT), //默认就是direct 类型
key = {"red","blue"}
))
public void listenDirectQueue1(String msg){
System.out.println("消费者接收到direct.queue1的消息:【" + msg + "】");
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "direct.queue2"),
exchange = @Exchange(name = "itcast.direct",type = ExchangeTypes.DIRECT), //默认就是direct 类型
key = {"red","yellow"}
))
public void listenDirectQueue2(String msg){
System.out.println("消费者接收到direct.queue2的消息:【" + msg + "】");
}
直接重新启动服务,
OK,启动成功
查看控制台的交换机
可以看到已经生成 了
点击查看详细信息
可以看到队列1 和队列2 都绑定了两个key
【发送消息】
举个栗子,指定把消息发送给blue
@Test
public void testSendDirectExchange(){
//交换机名称
String exchangeName = "itcast.direct";
//消息
String message = "Hello,blue!";
//发送消息
rabbitTemplate.convertAndSend(exchangeName,"blue",message);
}
直接运行测试
OK,发送成功
查看消费者那边的控制台
OK,效果很明显,只有队列1 收到并消费了消息
【只发给yellow】
@Test
public void testSendDirectExchange(){
//交换机名称
String exchangeName = "itcast.direct";
//消息
String message = "Hello,yellow!";
//发送消息
rabbitTemplate.convertAndSend(exchangeName,"yellow",message);
}
直接运行测试
OK,发送成功
效果很明显,这次就只有队列 2 收到了
【现在发给red 】【预期效果是两个队列都能收到】
@Test
public void testSendDirectExchange(){
//交换机名称
String exchangeName = "itcast.direct";
//消息
String message = "Hello,red!";
//发送消息
rabbitTemplate.convertAndSend(exchangeName,"red",message);
}
直接运行
OK,发送成功,直接查看控制台
OK,效果很明显,两个队列都收到了
【这就是direct 模式】
回顾一下
步骤1:
步骤2:
16.7.3 总结
描述下Direct交换机与Fanout交换机的差异?
- Fanout交换机将消息路由给每一个与之绑定的队列
- Direct交换机根据RoutingKey判断路由给哪个队列
- 如果多个队列具有相同的RoutingKey,则与Fanout功能类似
基于@RabbitListener注解声明队列和交换机有哪些常见注解?
- @Queue
- @Exchange