提前說一下,創建隊列,交換機,綁定交換機和隊列都是在生產者。消費者只負責監聽就行了,不用配其他的。
完成這個場景需要兩個服務哦。
1直連交換機-生產者的代碼。
在配置類中創建隊列,交換機,綁定交換機和隊列
@Configuration public class DirectRabbitConfigTest {//隊列@Beanpublic Queue TestDirectQueue(){return new Queue("TestDirectQueue",true);}//交換機@BeanDirectExchange TestDirectExchange(){return new DirectExchange("TestDirectExchange",true,false);}//綁定@BeanBinding bindingDirect(){return BindingBuilder.bind(TestDirectQueue()).to(TestDirectExchange()).with("TestDirectRouting");//TestDirectRouting為路由鍵} }
發送消息,訪問這個接口就行。
@Controller public class test001 {@Autowiredprivate RabbitTemplate rabbitTemplate;@ResponseBody@GetMapping("/sendDirectMessage")public String sendDirectMessage() {String messageId = String.valueOf(UUID.randomUUID());String messageData = "test message, hello!";String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));Map<String,Object> map=new HashMap<>();map.put("messageId",messageId);map.put("messageData",messageData);map.put("createTime",createTime);//將消息攜帶綁定鍵值:TestDirectRouting 發送到交換機TestDirectExchangerabbitTemplate.convertAndSend("TestDirectExchange", "TestDirectRouting", map);return "ok";} }
2直連交換機-消費者的代碼
@Component @RabbitListener(queues = "TestDirectQueue")//監聽的隊列 public class DirectReceiver {@RabbitHandlerpublic void process(Map testMessage){System.out.println("消息one:"+testMessage.toString());//這個map就是發送的消息} }
直連交換機總結:你可以自己加幾個消費者,發送消息你會發現消息被輪詢了。
訪問@GetMapping("/sendDirectMessage")消息就發出并被接收。
3topic交換機-生產者的代碼
注意:需要自己去控制臺添加firstQueue和secondQueue隊列,不然消費者啟動不起來。原因未知,在直連交換機的時候機器自己創建隊列了,topic不知道為啥不行。
@Configuration public class TopicRabbitConfigTest {//綁定鍵public final static String man = "topic.man";public final static String woman = "topic.woman";@Beanpublic Queue firstQueue() {//return new Queue(TopicRabbitConfigTest.man);return new Queue("firstQueue");}@Beanpublic Queue secondQueue() {//return new Queue(TopicRabbitConfigTest.woman);return new Queue("secondQueue");}@BeanTopicExchange exchange() {return new TopicExchange("topicExchange");}//將firstQueue和topicExchange綁定,而且綁定的鍵值為topic.man//這樣只要是消息攜帶的路由鍵是topic.man,才會分發到該隊列@BeanBinding bindingExchangeMessage() {return BindingBuilder.bind(firstQueue()).to(exchange()).with(man);}//將secondQueue和topicExchange綁定,而且綁定的鍵值為用上通配路由鍵規則topic.#// 這樣只要是消息攜帶的路由鍵是以topic.開頭,都會分發到該隊列@BeanBinding bindingExchangeMessage2() {return BindingBuilder.bind(secondQueue()).to(exchange()).with("topic.#");}}
發送消息,訪問這兩個接口就行。
@Controller public class TopicTest002 {@Autowiredprivate RabbitTemplate rabbitTemplate;@GetMapping("/sendTopicMessage1")public String sendTopicMessage1() {String messageId = String.valueOf(UUID.randomUUID());String messageData = "message: M A N ";String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));Map<String, Object> manMap = new HashMap<>();manMap.put("messageId", messageId);manMap.put("messageData", messageData);manMap.put("createTime", createTime);rabbitTemplate.convertAndSend("topicExchange", "topic.man", manMap);return "ok";}@GetMapping("/sendTopicMessage2")public String sendTopicMessage2() {String messageId = String.valueOf(UUID.randomUUID());String messageData = "message: woman is all ";String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));Map<String, Object> womanMap = new HashMap<>();womanMap.put("messageId", messageId);womanMap.put("messageData", messageData);womanMap.put("createTime", createTime);rabbitTemplate.convertAndSend("topicExchange", "topic.woman", womanMap);return "ok";} }
4topic交換機-消費者的代碼
需要監聽兩個隊列
@Component @RabbitListener(queues = "firstQueue")//監聽的隊列 public class TopicManReceiver {@RabbitHandlerpublic void process(Map testMessage) {System.out.println("TopicManReceiver消費者收到消息 : " + testMessage.toString());}}
@Component @RabbitListener(queues = "secondQueue")//監聽的隊列 public class TopicWoManReceiver {@RabbitHandlerpublic void process(Map testMessage) {System.out.println("TopicTotalReceiver消費者收到消息 : " + testMessage.toString());}}
先訪問@GetMapping("/sendTopicMessage1")接口,再訪@GetMapping("/sendTopicMessage2")接口,結果如下:
總結:綁定和發送的時候都要設置路由鍵。
5fanout交換機-生產者
注意:這種交換機也需要自己去控制臺創建隊列。fanout交換機不需要設置路由key
@Configuration public class FanoutRabbitConfigTest {/*** 創建三個隊列 :fanout.A fanout.B fanout.C* 將三個隊列都綁定在交換機 fanoutExchange 上* 因為是扇型交換機, 路由鍵無需配置,配置也不起作用*/@Beanpublic Queue queueA() {return new Queue("fanout.A");}@Beanpublic Queue queueB() {return new Queue("fanout.B");}@Beanpublic Queue queueC() {return new Queue("fanout.C");}@BeanFanoutExchange fanoutExchange() {return new FanoutExchange("fanoutExchange");}@BeanBinding bindingExchangeA() {return BindingBuilder.bind(queueA()).to(fanoutExchange());}@BeanBinding bindingExchangeB() {return BindingBuilder.bind(queueB()).to(fanoutExchange());}@BeanBinding bindingExchangeC() {return BindingBuilder.bind(queueC()).to(fanoutExchange());}}
發送消息,訪問這個接口就行。
@Controller public class FanoutTest003 {@Autowiredprivate RabbitTemplate rabbitTemplate;@GetMapping("/sendFanoutMessage")public String sendFanoutMessage() {String messageId = String.valueOf(UUID.randomUUID());String messageData = "message: testFanoutMessage ";String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));Map<String, Object> map = new HashMap<>();map.put("messageId", messageId);map.put("messageData", messageData);map.put("createTime", createTime);rabbitTemplate.convertAndSend("fanoutExchange", null, map);return "ok";}}
6fanout交換機-消費者
@Component @RabbitListener(queues = "fanout.A")//監聽的隊列 public class FanoutA {@RabbitHandlerpublic void process(Map testMessage) {System.out.println("FanoutReceiverA消費者收到消息 : " +testMessage.toString());} }
@Component @RabbitListener(queues = "fanout.B")//監聽的隊列 public class FanoutB {@RabbitHandlerpublic void process(Map testMessage) {System.out.println("FanoutReceiverB消費者收到消息 : " +testMessage.toString());}}
@Component @RabbitListener(queues = "fanout.C")//監聽的隊列 public class FanoutC {@RabbitHandlerpublic void process(Map testMessage) {System.out.println("FanoutReceiverC消費者收到消息 : " +testMessage.toString());}}
總結:三個消費者都收到了消息
重點:直連交換機不管綁定多少個隊列,消息會到達所有隊列,然后去消費者方進行輪詢。