Springboot使用RabbitMQ看這幾篇就夠了(模式案例篇)!

各位看官可以關注博主個人博客,瞭解更多信息。
作者:Surpasser
鏈接地址:https://surpass.org.cn

前言

上篇我們說到了消息隊列RabbitMQ的模式概念,那麼這裏將會針對模式使用SpringBoot聯合RabbitMQ做一個案例,實現消息的生產和消費。

這一篇也是這個主題的最後一篇了,建議配合着看。助於理解。

博主會將Demo工程放在Gitee上,有興趣的可以拉下來自己試試。

Gitee地址:https://gitee.com/lemon_ant/os.git

正文

準備工作

新建SpringBoot項目

添加配置文件

server.port=8080

spring.application.name=cl
#RabbitMq所在服務器IP
spring.rabbitmq.host=127.0.0.1
#連接端口號
spring.rabbitmq.port=5672
#用戶名
spring.rabbitmq.username=root
#用戶密碼
spring.rabbitmq.password=123456
# 開啓發送確認
spring.rabbitmq.publisher-confirm-type=correlated
# 開啓發送失敗退回
spring.rabbitmq.publisher-returns=true
spring.rabbitmq.virtual-host=/

添加pom文件

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-amqp</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework.amqp</groupId>
			<artifactId>spring-rabbit-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

啓動類

@SpringBootApplication
public class OsApplication {
	public static void main(String[] args) {
		SpringApplication.run(OsApplication.class, args);
	}

}

點對點模式

  1. 隊列初始化

    //當沒有這個隊列的時候會自動創建
    @Configuration
    public class PointInitialization {
        @Bean
        Queue toPoint(){
            Queue queue = new Queue("point.to.point",true);
            return queue;
        }
    }
    
  2. 生產者

    @Component
    public class PointProducer {
        @Autowired
        private RabbitTemplate rabbitTemplate;
    
        public void send(String name){
            String sendMsg = "點對點隊列:" + name + "   " + new Date();
            //指定隊列
          	this.rabbitTemplate.convertAndSend("point.to.point",sendMsg);
        }
    }
    
  3. 消費者

    @Component
    public class PointConsumer {
    	//監聽的隊列名
        @RabbitListener(queues = "point.to.point")
        public void processOne(String name) {
            System.out.println("point.to.point:" + name);
        }
    
    }
    
  4. 測試類(模仿控制層)

    @RestController
    @RequestMapping("/Point")
    public class PointController {
        @Autowired
        private PointProducer sayProducer;
    
        @RequestMapping("/point/{name}")
        public String send(@PathVariable String name){
            sayProducer.send(name);
            return "發送成功";
        }
    }
    
  5. 使用postman模擬請求

  1. 控制檯結果

work模式

  1. 隊列初始化

    @Configuration
    public class WorkInitialization {
        //當沒有這個隊列的時候會自動創建
        @Bean
        Queue work(){
            Queue queue = new Queue("WorkingMode",true);
            return queue;
        }
    }
    
  2. 生產者

    @Component
    public class WorkProducer {
    
        @Autowired
        private RabbitTemplate rabbitTemplate;
    
        public void send(String name){
            String sendMsg = "工作模式:" + name + "   " + new Date();
            //指定隊列
            this.rabbitTemplate.convertAndSend("WorkingMode",sendMsg);
        }
    }
    
  3. 消費者

    //三個隊列同時監聽
    @Component
    public class WorkConsumer {
        @RabbitListener(queues = "WorkingMode")
        public void processOne(String name) {
            System.out.println("WorkingMode1:" + name);
        }
    
        @RabbitListener(queues = "WorkingMode")
        public void processTwo(String name) {
            System.out.println("WorkingMode2:" + name);
        }
    
        @RabbitListener(queues = "WorkingMode")
        public void processThree(String name) {
            System.out.println("WorkingMode3:" + name);
        }
    
    }
    
  4. 測試類(模仿控制層)

    @RestController
    @RequestMapping("/work")
    public class WorkController {
    
        @Autowired
        private WorkProducer sayProducer;
    
        @RequestMapping("/work/{name}")
        public String send(@PathVariable String name){
            sayProducer.send(name);
            return "發送成功";
        }
    }
    
  5. 使用postman模擬請求

  1. 控制檯結果

注意看時間,說明消息是輪詢分發的,一個消息只由一個消費者消費。

發佈/訂閱者模式(Publish/Subscribe)

  1. 隊列初始化

    //類型爲fanout
    @Configuration
    public class PublishInitialization {
    
        //當沒有這個隊列的時候會自動創建
        @Bean
        Queue publishOne(){
            Queue queue = new Queue("queue.publish.one",true);
            return queue;
        }
        @Bean
        Queue publishTwo(){
            Queue queue = new Queue("queue.publish.two",true);
            return queue;
        }
        @Bean
        Queue publishThree(){
            Queue queue = new Queue("queue.publish.three",true);
            return queue;
        }
    
        //創建交換器
        @Bean
        FanoutExchange pulishExchange(){
            FanoutExchange directExchange = new FanoutExchange("publishExchange");
            return directExchange;
        }
    
        //綁定隊列(不用指定routing key),參數名字要和bean名字一致
        @Bean
        Binding bindingPublishOne(Queue publishOne,FanoutExchange pulishExchange){
            Binding binding = BindingBuilder.bind(publishOne).to(pulishExchange);
            return binding;
        }
        @Bean
        Binding bindingPublishTwo(Queue publishTwo,FanoutExchange pulishExchange){
            Binding binding = BindingBuilder.bind(publishTwo).to(pulishExchange);
            return binding;
        }
        @Bean
        Binding bindingPublishThree(Queue publishThree,FanoutExchange pulishExchange){
            Binding binding = BindingBuilder.bind(publishThree).to(pulishExchange);
            return binding;
        }
    }
    
  2. 生產者

    @Component
    public class PublishProducer {
        @Autowired
        private RabbitTemplate rabbitTemplate;
    
        public void send(String name){
            String sendMsg = "發佈訂閱模式:" + name + "   " + new Date();
            //指定隊列
            this.rabbitTemplate.convertAndSend("publishExchange","",sendMsg);
        }
    }
    
  3. 消費者

    @Component
    public class PublishConsumer {
        @RabbitListener(queues = "queue.publish.one")
        public void processOne(String name) {
            System.out.println("queue.publish.one:" + name);
        }
    
        @RabbitListener(queues = "queue.publish.two")
        public void processTwo(String name) {
            System.out.println("queue.publish.two:" + name);
        }
    
        @RabbitListener(queues = "queue.publish.three")
        public void processThree(String name) {
            System.out.println("queue.publish.three:" + name);
        }
    }
    
  4. 測試類(模仿控制層)

    @RestController
    @RequestMapping("/Publish")
    public class PublishController {
    
        @Autowired
        private PublishProducer sayProducer;
    
        @RequestMapping("/publish/{name}")
        public String send(@PathVariable String name){
            sayProducer.send(name);
            return "發送成功";
        }
    }
    
  5. 使用postman模擬請求

  1. 控制檯結果

注意看時間,交換機會將消息推送到所有綁定到它的隊列。

路由模式

  1. 隊列初始化

    //類型爲direct
    @Configuration
    public class RoutingInitialization {
    
        //當沒有這個隊列的時候會自動創建
        @Bean
        Queue routingOne(){
            Queue queue = new Queue("queue.routing.one",true);
            return queue;
        }
        @Bean
        Queue routingTwo(){
            Queue queue = new Queue("queue.routing.two",true);
            return queue;
        }
        @Bean
        Queue routingThree(){
            Queue queue = new Queue("queue.routing.three",true);
            return queue;
        }
    
        //創建交換器
        @Bean
        DirectExchange routingExchange(){
            DirectExchange directExchange = new DirectExchange("routingExchange");
            return directExchange;
        }
    
        //綁定隊列
        @Bean
        Binding bindingRoutingOne(Queue routingOne,DirectExchange routingExchange){
            Binding binding = BindingBuilder.bind(routingOne).to(routingExchange).with("1");
            return binding;
        }
        @Bean
        Binding bindingRoutingTwo(Queue routingTwo,DirectExchange routingExchange){
            Binding binding = BindingBuilder.bind(routingTwo).to(routingExchange).with("2");
            return binding;
        }
        @Bean
        Binding bindingRoutingThree(Queue routingThree,DirectExchange routingExchange){
            Binding binding = BindingBuilder.bind(routingThree).to(routingExchange).with("3");
            return binding;
        }
    }
    
  2. 生產者

    @Component
    public class RoutingProducer {
    
        @Autowired
        private RabbitTemplate rabbitTemplate;
    
        public void send(String type){
            String sendMsg = "路由模式:" + type + "   " + new Date();
            //指定隊列
            if (type.equals("1")){
                this.rabbitTemplate.convertAndSend("routingExchange","1",sendMsg);
            }
            if (type.equals("2")){
                this.rabbitTemplate.convertAndSend("routingExchange","2",sendMsg);
            }
            if (type.equals("3")){
                this.rabbitTemplate.convertAndSend("routingExchange","3",sendMsg);
            }
        }
    }
    
  3. 消費者

    @Component
    public class RoutingConsumer {
    
    
        @RabbitListener(queues = "queue.routing.one")
        public void processOne(String name) {
            System.out.println("queue.routing.one:" + name);
        }
    
        @RabbitListener(queues = "queue.routing.two")
        public void processTwo(String name) {
            System.out.println("queue.routing.two:" + name);
        }
    
        @RabbitListener(queues = "queue.routing.three")
        public void processThree(String name) {
            System.out.println("queue.routing.three:" + name);
        }
    
    }
    
  4. 測試類(模仿控制層)

    @RestController
    @RequestMapping("/Routing")
    public class RoutingController {
    
        @Autowired
        private RoutingProducer sayProducer;
    
        @RequestMapping("/routing/{name}")
        public String send(@PathVariable String name){
            sayProducer.send(name);
            return "發送成功";
        }
    }
    
  5. 使用postman模擬請求

我這裏測試傳的就是routing key,方便看。

  1. 控制檯結果

這裏用時間來區別。

主題模式(Topic)

  1. 隊列初始化

    //類型爲topic
    @Configuration
    public class TopicInitialization {
    
        //當沒有這個隊列的時候會自動創建
        @Bean
        Queue topicOne(){
            Queue queue = new Queue("queue.topic.one",true);
            return queue;
        }
        @Bean
        Queue topicTwo(){
            Queue queue = new Queue("queue.topic.two",true);
            return queue;
        }
        @Bean
        Queue topicThree(){
            Queue queue = new Queue("queue.topic.three",true);
            return queue;
        }
    
        //創建交換器
        @Bean
        TopicExchange topicExchange(){
            TopicExchange directExchange = new TopicExchange("topicExchange");
            return directExchange;
        }
    
        //綁定隊列
        @Bean
        Binding bindingTopicOne(Queue topicOne,TopicExchange topicExchange){
            Binding binding = BindingBuilder.bind(topicOne).to(topicExchange).with("#.error");
            return binding;
        }
        @Bean
        Binding bindingTopicTwo(Queue topicTwo,TopicExchange topicExchange){
            Binding binding = BindingBuilder.bind(topicTwo).to(topicExchange).with("#.log");
            return binding;
        }
        @Bean
        Binding bindingTopicThree(Queue topicThree,TopicExchange topicExchange){
            Binding binding = BindingBuilder.bind(topicThree).to(topicExchange).with("good.#.timer");
            return binding;
        }
    }
    
  2. 生產者

    @Component
    public class TopicProducer {
    
        @Autowired
        private RabbitTemplate rabbitTemplate;
    
        public void send(String routing){
            String sendMsg = "主題模式:" + routing + "   " + new Date();
            //指定隊列
            this.rabbitTemplate.convertAndSend("topicExchange",routing,sendMsg);
    
        }
    }
    
  3. 消費者

    @Component
    public class TopicConsumer {
        @RabbitListener(queues = "queue.topic.one")
        public void processOne(String name) {
            System.out.println("queue.topic.one:" + name);
        }
    
        @RabbitListener(queues = "queue.topic.two")
        public void processTwo(String name) {
            System.out.println("queue.topic.two:" + name);
        }
    
        @RabbitListener(queues = "queue.topic.three")
        public void processThree(String name) {
            System.out.println("queue.topic.three:" + name);
        }
    
    }
    
  4. 測試類(模仿控制層)

    @RestController
    @RequestMapping("/Topic")
    public class TopicController {
    
        @Autowired
        private TopicProducer sayProducer;
    
        @RequestMapping("/topic/{type}")
        public String send(@PathVariable String type){
            sayProducer.send(type);
            return "發送成功";
        }
    }
    
  5. 請求以及對應結果


    • 注意看請求的key和打印日誌的對應關係。

尾言

消息隊列在這裏基本就結束了,結合前面兩篇基本就能夠了解隊列的基本概念和用法了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章