定义生产者的微服务:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
spring:
application:
name: rabbitmq-product
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
#消息确认配置项
#确认消息已发送到交换机
publisher-confirms: true
#确认消息已发送到队列
publisher-returns: true
server:
port: 9393
定义配置类,声明交换机,队列,并且将交换机和队列进行绑定。
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 直连型的交换机,消费者不一定需要添加交换机声明的相关配置
*/
@Configuration
public class DirectRabbitmqConfig {
/**
* 声明队列
* @return
*/
@Bean
public Queue directQueue(){
return new Queue("directQueue",true);
}
/**
* 声明直连型交换机
* @return
*/
@Bean
public DirectExchange directExchange(){
return new DirectExchange("directExchange",true,false);
}
/**
* 声明直连型交换机
* @return
*/
@Bean
public DirectExchange callBackExchange(){
return new DirectExchange("callBackExchange",true,false);
}
/**
* 将交换机和队列绑定,并设置匹配键directQueueTest1
* @return
*/
@Bean
public Binding bindingDirect(){
return BindingBuilder.bind(directQueue()).to(directExchange()).with("directQueueTest1");
}
}
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 扇形交换机
* 创建三个队列,将三个队列都绑定到交换机上,因为是扇形交换机,路由键无需配置,配置了也不起作用
*/
@Configuration
public class FanoutRabbitmqConfig {
/**
* 声明队列fanoutQueue1
* @return
*/
@Bean
public Queue fanoutQueue1(){
return new Queue("fanoutQueue1");
}
/**
* 声明队列fanoutQueue2
* @return
*/
@Bean
public Queue fanoutQueue2(){
return new Queue("fanoutQueue2");
}
/**
* 声明队列fanoutQueue3
* @return
*/
@Bean
public Queue fanoutQueue3(){
return new Queue("fanoutQueue3");
}
/**
* 声明扇形交换机
* @return
*/
@Bean
public FanoutExchange fanoutExchange(){
return new FanoutExchange("fanoutExchange");
}
//将三个队列和交换机进行绑定
@Bean
public Binding bindingFanoutExchange1(){
return BindingBuilder.bind(fanoutQueue1()).to(fanoutExchange());
}
@Bean
public Binding bindingFanoutExchange2(){
return BindingBuilder.bind(fanoutQueue2()).to(fanoutExchange());
}
@Bean
public Binding bindingFanoutExchange3(){
return BindingBuilder.bind(fanoutQueue3()).to(fanoutExchange());
}
}
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Topic Exchange主题交换机
*/
@Configuration
public class TopicRabbitmqConfig {
//声明绑定键
public static final String stock1 = "topic.stock1";
public static final String stock2 = "topic.stock2";
/**
* 声明队列1
* @return
*/
@Bean
public Queue topicQueue1(){
return new Queue(TopicRabbitmqConfig.stock1);
}
/**
* 声明队列2
* @return
*/
@Bean
public Queue topicQueue2(){
return new Queue(TopicRabbitmqConfig.stock2);
}
/**
* 声明交换机
* @return
*/
@Bean
public TopicExchange topicExchange(){
return new TopicExchange("topicExchange");
}
/**
* 将topicQueue1和topicExchange绑定,而且绑定的键值为topic.man
* 这样只要是消息携带的路由键是topic.man,才会分发到该队列
* @return
*/
@Bean
public Binding bindingExchange1(){
return BindingBuilder.bind(topicQueue1()).to(topicExchange()).with(stock1);
}
/**
* 将topicQueue2和topicExchange绑定,而且绑定的键值为用上通配路由键规则topic.#
* 这样只要是消息携带的路由键是以topic.开头,都会分发到该队列
* @return
*/
@Bean
public Binding bindingExchange2(){
return BindingBuilder.bind(topicQueue2()).to(topicExchange()).with("topic.#");
}
}
写一个类实现消息的推送:
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@RestController
@RequestMapping("/mq")
public class DirectrmqController {
@Autowired
RabbitTemplate rabbitTemplate;
/**
* 直连型交换机推送消息
* @return
*/
@GetMapping("/test1")
public String testDirectmq(){
Map mqMap = new HashMap();
mqMap.put("id", UUID.randomUUID().toString().replace("-",""));
mqMap.put("name","yang");
String receive = (String) rabbitTemplate.convertSendAndReceive("directExchange", "directQueueTest1", mqMap);
System.out.println(receive);
return "ok";
}
/**
* 主题型交换机推送消息
* @return
*/
@GetMapping("/topic1")
public String testTopicmq(){
String message = "stock1发送消息了";
String receive = (String) rabbitTemplate.convertSendAndReceive("topicExchange","topic.stock1",message);
return receive;
}
@GetMapping("/topic2")
public String testTopicmq2(){
String message = "stock2发送消息了";
String receive = (String) rabbitTemplate.convertSendAndReceive("topicExchange","topic.stock2",message);
return receive;
}
/**
* 扇形交换机推动消息,路由键为空
* @return
*/
@GetMapping("/fanout")
public String testFanoutmq(){
String messge = "Fanoutmq发送消息啦";
rabbitTemplate.convertSendAndReceive("fanoutExchange",null,messge);
return "ok";
}
/**
* 测试推送消息确认机制
* @return
*/
@GetMapping("/testRabbitmqCallBack")
public String testRabbitmqCallBack(){
String message = "测试mq回调发送消息了";
rabbitTemplate.convertSendAndReceive("callBackExchange","test",message);
return "ok";
}
}
消费者服务:rabbitmq-comsumer
直连型交换机配置多台监听(相当于多个消费者)绑定到同一个直连交互的同一个队列,将采用轮询的方式对消息进行消费,而且不存在重复消费
@Component
public class DirectReceiver {
@SendTo("directQueue")
@RabbitHandler
@RabbitListener(queues = "directQueue")
public String comsumeDirectQueue(Map message){
System.out.println("DirectReceiver1消费者收到消息:" + message);
return "SUCCESS1";
}
}
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* 配置多台监听(相当于多个消费者)绑定到同一个直连交互的同一个队列
* 轮询的方式对消息进行消费,而且不存在重复消费
*/
@Component
public class DirectReceiver2 {
@RabbitListener(queues = "directQueue")
@RabbitHandler
@SendTo("directQueue")
public String comsumeDirectQueue(Map message){
System.out.println("DirectReceiver2消费者收到消息:" + message);
return "SUCCESS2";
}
}
扇形交换机消费
@Component
public class FanoutReceiver {
@RabbitListener(queues = "fanoutQueue1")
@RabbitHandler
public void comsumeFanoutQueue1(String msg){
System.out.println("fanoutReceiver1接受到消息了" + msg);
}
@RabbitListener(queues = "fanoutQueue2")
@RabbitHandler
public void comsumeFanoutQueue2(String msg){
System.out.println("fanoutReceiver2接受到消息了" + msg);
}
@RabbitListener(queues = "fanoutQueue3")
@RabbitHandler
public void comsumeFanoutQueue3(String msg){
System.out.println("fanoutReceiver3接受到消息了" + msg);
}
}
主题型交换机消费:
@Component
public class TopicReceiver {
@RabbitListener(queues = "topic.stock1")
@RabbitHandler
@SendTo("topicQueue1")
public String comsumeDirectQueue(String message){
System.out.println("topic1消费者收到消息:" + message);
return "SUCCESS1";
}
@RabbitListener(queues = "topic.stock2")
@RabbitHandler
@SendTo("topicQueue2")
public String comsumeDirectQueue2(String message){
System.out.println("topic2消费者收到消息:" + message);
return "SUCCESS2";
}
}
参考:https://blog.csdn.net/qq_35387940/article/details/100514134