SpringBoot+rabbitmq实现其六种工作模式

介绍

rabbitmq有六种工作模式。我们使用springboot整合实现rabbitmq的六种工作模式,并在其中谈及如何调用ack。
在这里插入图片描述

准备工作

导入springboot的rabbitmq的场景,还有一个web场景

      <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>

然后设置yaml里面的配置文件,

server:
  port: 5672

spring:
  rabbitmq:
    host: 192.168.80.88  #mq服务器ip,默认为localhost
    port: 5672          #mq服务器port,默认为5672
    username: guest     #mq服务器username,默认为gust
    password: guest     #mq服务器password,默认为guest

实现

简单模式

简单模式也可以称为hello-world模式,我们使用默认的交换机,只需要声明队列,消费者和生产者
在这里插入图片描述
先创建队列

    @Bean
    public Queue Queue() {
        return new Queue("hello");
    }

然后创建生产者

@Controller
public class HelloSender {

    @Autowired
    private AmqpTemplate rabbitTemplate;

    public void send() {
        String context = "hello " + new Date();
        System.out.println("Sender : " + context);
        this.rabbitTemplate.convertAndSend("hello", context);
    }
}

再创建消费者

@Component
@RabbitListener(queues = "hello")
public class HelloReceiver {
    @RabbitHandler
    public void process(String hello) {
        System.out.println("Receiver  : " + hello);
    }
}

再写一个测试用例看看

@RunWith(SpringRunner.class)
@SpringBootTest
public class RabbitmqApplicationTests {
        @Autowired
        private HelloSender helloSender;

        @Test
        public void hello() throws Exception {
            helloSender.send();
        }
}

工作模式

工作模式就是在简单模式上添加多个消费者,在此我们使用的是默认交换机

在这里插入图片描述

我们先创建一个队列

   @Bean
    public Queue Queue2() {
        return new Queue("neo");
    }

再创建一个消息生产者

@Controller
public class NeoSender {
    @Autowired
    private AmqpTemplate rabbitTemplate;

    public void send(int i) {
        String context = "spirng boot neo queue"+" ****** "+i;
        System.out.println("Sender1 : " + context);
        this.rabbitTemplate.convertAndSend("neo", context);
    }
}

再创建两个消息的消费者

 @Component
 @RabbitListener(queues = "neo")
 public class NeoReceiver1 {
     @RabbitHandler
    public void process(String neo) {
       System.out.println("Receiver 1: " + neo);
    }
  }
 
 
 @Component
 @RabbitListener(queues = "neo")
 public class NeoReceiver2 {
     @RabbitHandler
     public void process(String neo) {
         System.out.println("Receiver 2: " + neo);
     } 
 }

我们写一个测试用例

@Test
    public void oneToMany() throws Exception {
        for (int i=0;i<1000;i++){
            neoSender.send(i);
        }
    }

发布订阅模式

在这里插入图片描述
在发布订阅模式下,生产者将消息发送到X交换机,然后由交换机发送给两个队列,两个消费者各自监听一个队列,来消费消息。

这种方式实现同一个消息被多个消费者消费。工作模式是同一个消息只能有一个消费者。

我们新建三个队列

@Bean
    public Queue AMessage() {
        return new Queue("fanout.A");
    }

    @Bean
    public Queue BMessage() {
        return new Queue("fanout.B");
    }

    @Bean
    public Queue CMessage() {
        return new Queue("fanout.C");
    }

再新建一个交换机

@Bean
    FanoutExchange fanoutExchange() {
        return new FanoutExchange("fanoutExchange");
    }

再把这些队列绑定到交换机上去

@Bean
    Binding bindingExchangeA(Queue AMessage, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(AMessage).to(fanoutExchange);
    }

    @Bean
    Binding bindingExchangeB(Queue BMessage, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(BMessage).to(fanoutExchange);
    }

    @Bean
    Binding bindingExchangeC(Queue CMessage, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(CMessage).to(fanoutExchange);
    }

基本的配置完成后,再新建一个消息生产者

@Component
public class FanoutSender {
    @Autowired
    private AmqpTemplate rabbitTemplate;

    public void send() {
        String context = "hi, fanout msg ";
        System.out.println("Sender : " + context);
        this.rabbitTemplate.convertAndSend("fanoutExchange","", context);
    }
}

同样的,我们再新建三个消息消费者

 @Component
 @RabbitListener(queues = "fanout.A")
 public class FanoutReceiveA {

     @RabbitHandler
     public void process(String message) {
         System.out.println("fanout Receiver A  : " + message);
     }
 }

 @Component
 @RabbitListener(queues = "fanout.B")
 public class FanoutReceiverB {
     @RabbitHandler
     public void process(String message) {
         System.out.println("fanout Receiver B: " + message);
     }
 }
 
 @Component
 @RabbitListener(queues = "fanout.C")
 public class FanoutReceiverC {
     @RabbitHandler
     public void process(String message) {
         System.out.println("fanout Receiver C: " + message);
    }
 }

三个消费者分别监听3个队列的内容,然后新建一个测试用例:

@RunWith(SpringRunner.class)
@SpringBootTest
public class FanoutTest {
    @Autowired
    private FanoutSender fanoutSender;

    @Test
    public void setFanoutSender(){
        fanoutSender.send();
    }
}

在这里插入图片描述

路由模式

在这里插入图片描述
需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配,这是一个完整的匹配。
路由模式的代码和主题模式放在一起

主题模式

发送端不只按固定的routing key发送消息,而是按字符串匹配发送,接收端同样如此

符号#匹配一个或多个词,符号*匹配不多不少一个词。
在这里插入图片描述
新建两个队列

    final static String message = "topic.A";
    final static String messages = "topic.B";


    @Bean
    public Queue queueMessage() {
        return new Queue(TopicRabbitConfig.message);
    }

    @Bean
    public Queue queueMessages() {
        return new Queue(TopicRabbitConfig.messages);
    }

新建一个交换机

    @Bean
    TopicExchange exchange() {
        return new TopicExchange("topicExchange");
    }

绑定队列到交换机上,路由模式,需要完整匹配topic.message,才能接受

@Bean
    Binding bindingExchangeMessage(Queue queueMessage, TopicExchange exchange) {
        return BindingBuilder.bind(queueMessage).to(exchange).with("topic.message");
    }

topic模式,前缀匹配到topic.即可接受

@Component
public class TopicSend {
    @Autowired
    private AmqpTemplate rabbitTemplate;

    public void send() {
        String context = "hi, i am message all";
        System.out.println("Sender : " + context);
        this.rabbitTemplate.convertAndSend("topicExchange", "topic.1", context);
    }

    public void send1() {
        String context = "hi, i am message 1";
        System.out.println("Sender : " + context);
        this.rabbitTemplate.convertAndSend("topicExchange", "topic.message", context);
    }

    public void send2() {
        String context = "hi, i am messages 2";
        System.out.println("Sender : " + context);
        this.rabbitTemplate.convertAndSend("topicExchange", "topic.messages", context);
    }
}

我们新建三个消息生产者

send的key是topic.1 send1的key是topic.message,send2的key是topic.messages

所以理论上send会被两个队列消费,1.2都应该只有一个队列消费

我们再新建两个消费者

@Component
@RabbitListener(queues = "topic.A")
public class TopicReceiver {
    @RabbitHandler
    public void process(String message) {
        System.out.println("Topic Receiver1  : " + message);
    }

}

@Component
@RabbitListener(queues = "topic.B")
public class TopicReceiver2 {
    @RabbitHandler
    public void process(String message) {
        System.out.println("Topic Receiver2  : " + message);
    }
}

写三个测试用例

@RunWith(SpringRunner.class)
@SpringBootTest
public class TopicTest {
    @Autowired
    private TopicSend sender;

    @Test
    public void topic() throws Exception {
        sender.send();
    }

    @Test
    public void topic1() throws Exception {
        sender.send1();
    }

    @Test
    public void topic2() throws Exception {
        sender.send2();
    }

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值