DirectExchange,咱们看名字可以看的出来,是一种交换机,那我们首先要了解咱们的一个架构了,咱们的消息提供者发送消息根据交换机,把消息放在交换机绑定的消息队列上,然后消息的消费者,再去消费队列的消息,DirectExchange,其实交换机就是在做一个消息的分发、将提供者的消息分发到对应的队列上,DirectExchange,就可以根据对应的路由将消息放在对应的一个队列上。然后消息的消费者再去对应的队列里面去监听和消费消息。
通俗来讲就是定向的交换机,根据路由和消息队列进行绑定。
看文字可能不是很直观,看图秒懂,来看操作。
如何去实现呢,之前我记得用Java实现过一次,不过现在咱们可以用更简便的springboot的去实现这么一件事情。使咱们的代码更加的简洁。
第一步,创建两个springboot项目、一个作消费者(consumer),一个作提供者(provider),下面是项目的目录:
紧接着在父工程中导入咱们的依赖
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-amqp
首先是咱们的消息提供者mq-provider
application.yml配置文件:
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
virtual-host: /
紧接着就去声明咱们的队列,和交换机,编写config
DirectRabbitConfig
/**
* @author shenwang
* @version 1.0
*/
@Configuration
public class DirectRabbitConfig {
/**
* 交换机
* @return
*/
@Bean
public DirectExchange myDirectExchange(){
/**
* name 名称
* durable 持久化
* autoDelete 自动删除
*/
return new DirectExchange("myDirectExchange",true,false);
}
/**
* 队列
* @return
*/
@Bean
public Queue myDirectQueue(){
return new Queue("myDirectQueue",true);
}
/**
* 绑定
* @return
*/
@Bean
public Binding bindingDirect(){
return BindingBuilder.bind(myDirectQueue()).to(myDirectExchange()).with("my.direct.routing");
}
/**
* 用来存放订单消息的队列
* @return
*/
@Bean
public Queue myDirectQueueOfOrder(){
return new Queue("myDirectQueueOfOrder",true);
}
/**
* 绑定订单的消息队列
* @return
*/
@Bean
public Binding bindingDirectOrder(){
return BindingBuilder.bind(myDirectQueueOfOrder()).to(myDirectExchange()).with("my.direct.routing.order");
}
}
我解释一下,有两个队列,myDirectQueue和myDirectQueueOfOrder,它们和交换机对应的路由分别是,my.direct.routing,和 my.direct.routing.order 咱们发消息的时候就可以根据路由将消息发送到对应的消息队列中,下面咱们用controller层写两个方法,用来发送向着两个队列消息。
/**
* @author shenwang
* @version 1.0
*/
@RestController
@RequestMapping("/mq")
public class RabbitmqController {
@Autowired
private RabbitTemplate rabbitTemplate;
@GetMapping("/send")
public String send(){
String message="hello world!!!";
rabbitTemplate.convertAndSend("myDirectExchange","my.direct.routing",message);
return "success!!!";
}
@GetMapping("/sendOrder")
public String sendOrder(){
String message="您的订单已成功生成";
rabbitTemplate.convertAndSend("myDirectExchange","my.direct.routing.order",message);
return "success!!!";
}
}
然后咱们去测试一下。
启动项目
然后访问localhost:8080/mq/send和locahost:8080/mq/sendOrder
可以看到,咱们两个消息队列都声明成功啦
咱们先点进myDirectQueue里面去看一下
可以看到咱们的消息已经发送成功了,咱们再去myDirectQueueOfOrder里面去看一下
也是成功的发送了消息,over到这里咱们消息的提供者就弄完啦,咱们去写咱们的消费者对这两个队列的消息进行一个消息的监听和消费吧
mq-comsumer它的application.yml其实也不用写,因为它默认的账号就是guest,虚拟地址是 /
但是有需要的小伙伴可以自己去配一下,我这只配了一个端口为了防止两个项目端口冲突。如果非要写的话,和咱们消息提供者的信息对应上就好啦
消息的监听和消费无非也就两个注解,@RabbitHandler,@RabbitListener直接上代码,一秒懂:
/**
* 消息处理者
* @author shenwang
* @version 1.0
*/
@Component
public class DirectReceiver {
@RabbitHandler
@RabbitListener(queues = "myDirectQueueOfOrder")
public void processOrder(String message){
System.out.println("myDirectQueueOfOrder的消息:");
System.out.println("message:"+message);
}
@RabbitHandler
@RabbitListener(queues = "myDirectQueue")
public void process(String message){
System.out.println("myDirectQueue的消息:");
System.out.println("message:"+message);
}
}
启动一下咱们的消费者:
这样就成功的消费了咱们的消息啦,
咱们先清空console(控制台)再次请求 localhost:8080/mq/sendOrder
直接监听到窝,是不是有点爽呢,悟了吗