rabbitmq

rabbitmq的几种模式:一共有7种模式

rabbitmq_第1张图片

 3,4,5三个模式涉及到交换机

安装rabbotmq到虚拟机里面 。默认账户guest,密码也是guest

rabbitmq_第2张图片

进来之后可以看到管控台:

rabbitmq_第3张图片

 引入依赖:

 rabbitmq_第4张图片

在yml文件中 配置rabbitmq的信息:

rabbitmq:
   host:192.168.10.101
   username:guest
   password:guest
   virtual-host:/    //虚拟主机
   port:5672
   listener:
      simple:
         concurrency:10   //消费者的最小数量
         max-concurrency:10    //消费者最大数量
         prefetch:1     //限制消费者每次只处理一条消息,处理完再继续下一条消息
         auto-startup:true  //启动时是否默认启动容器,默认为true
         default-requeue-rejected:true  //被拒绝时重新进入队列
   template:
      
              
     

Rabbitmq是一个典型的生产者消费者模型,创建一个队列queue

@Configuration
public  class   RabbitMQConfig
{
    @Bean
    public  Queue    queue()
    {
        return   new   Queue("queue",true);//队列名称就叫queue,消息持久化

    }
}

消息发送方:发送对象

@Service
@Slf4j
public   class MQSender
{
   @Autowired
   private   RabbitTemplate  rabbitTemplate;
 

   public  void  send(Object msg)
   {

      //发送消息之前(发送的是一个对象),先把消息打印出来
      log.info(msg);
      
     //发送消息到队列里面
      rabbitTemplate.convertAndSend("queue",msg);
      
 
   }

}

消息接收方:消费者

@Service
@Slf4j
public   class MQReceiver
{

   @RabbitListener(queue="queue")  //监听叫queue的这个队列
   public  void  receive(Object msg)
   {

      //把消息打印出来
      log.info(msg);
      

   }
}

 测试发送消息

@Controller
@RequestMapping("/user")
public  class  UserController
{
   @Autowired   
   private   MQSender  mqSender;
   
   @RequestMapping("/mq")
   @ResponseBody 
   public  void  mq()
   {
       mqSender.send("Hello");    
   }
}

 这个链接是消费者去连接的,因为发送者发完消息就会关掉,消费者会一直监听队列

rabbitmq_第5张图片

现在还没有发送消息,所以 队列里面一直是0rabbitmq_第6张图片

 发了消息之后:

rabbitmq_第7张图片

fanout模式:发布订阅模式,也就是广播模式,消息可以被多个队列接收,多个队列接收的是同一个消费者发送的同一个消息

这里new了两个队列和一个交换机

@Configuration
public  class   RabbitMQConfig
{
    @Bean
    public  Queue    queue01()
    {
        return   new   Queue("queue01",true);//队列名称就叫queue,消息持久化

    }

    @Bean
    public  Queue    queue02()
    {
        return   new   Queue("queue01",true);//队列名称就叫queue,消息持久化
    } 

    @Bean  //创建一个交换机
    public   FanoutExchange  fanoutExchange()
    {
         return  new  FanoutExchange("fanoutExchange");
    }

    //将队列绑定到交换机上面去
    @Bean
    public    Binding  binding01()
    {
       return   BindingBuilder.bind(queue01()).to(fanoutExchange());
    }
    @Bean
    public    Binding  binding02()
    {
       return   BindingBuilder.bind(queue02()).to(fanoutExchange());
    }
}

然后消息发送方把消息发送到交换机里面,而不是队列中

@Service
@Slf4j
public   class MQSender
{
   @Autowired
   private   RabbitTemplate  rabbitTemplate;
 

   public  void  send(Object msg)
   {

      //发送消息之前(发送的是一个对象),先把消息打印出来
      log.info(msg);
      
     //发送消息到队列里面
      rabbitTemplate.convertAndSend("fanoutExchange","",msg); 
   }

}

 接收方(消费者)需要监听两个队列:

@Service
@Slf4j
public   class MQReceiver
{

   @RabbitListener(queue="queue01")  //监听叫queue的这个队列
   public  void  receive(Object msg)
   {

      //把消息打印出来
      log.info(msg);
   }

   @RabbitListener(queue="queue02")  //监听叫queue的这个队列
   public  void  receive(Object msg)
   {

      //把消息打印出来
      log.info(msg);
   }
}

direct模式

你发送的消息里路由key是black,就会发送到queue2队列里面去

你发送的消息里路由key是orange,就会发送到queue1队列里面去

也就是说由路由key来指定发送到哪个队列里面

rabbitmq_第8张图片

@Configuration
public  class   RabbitMQDirectConfig
{
    @Bean
    public  Queue    queue01()
    {
        return   new   Queue("queue01");//队列名称就叫queue,消息持久化

    }

    @Bean
    public  Queue    queue02()
    {
        return   new   Queue("queue02");//队列名称就叫queue,消息持久化

    }

    //定义交换机
    pubcli  DirectExchange  directExchange()
    {
       return  new  DirectExchange("direchExchange");
    }

    @Bean  //绑定队列到交换机,需要带上路由键route key
    public    Binding  binding01()
    {
       return   BindingBuilder.bind(queue01()).to(directExchange()).with(queue.red);
    }

    @Bean  //绑定队列到交换机,需要带上路由键route key
    public    Binding  binding02()
    {
       return   BindingBuilder.bind(queue02()).to(directExchange()).with(queue.green);
    }
}

消息发送方:发送对象

@Service
@Slf4j
public   class MQSender
{
   @Autowired
   private   RabbitTemplate  rabbitTemplate;
 
   public  void  send01(Object msg)
   {

      //发送消息之前(发送的是一个对象),先把消息打印出来
      log.info(msg);
      
     //发送消息到交换机里面
      rabbitTemplate.convertAndSend("directExchange","queue.red",msg); 
      
   }

   public  void  send02(Object msg)
   {

      //发送消息之前(发送的是一个对象),先把消息打印出来
      log.info(msg);
      
     //发送消息到交换机里面
      rabbitTemplate.convertAndSend("directExchange","queue.green",msg); 
      
   }
}

消息接收方:消费者

@Service
@Slf4j
public   class MQReceiver
{

   @RabbitListener(queue="queue01")  //监听叫queue的这个队列
   public  void  receive01(Object msg)
   {

      //把消息打印出来
      log.info(msg);
   }

   @RabbitListener(queue="queue02")  //监听叫queue的这个队列
   public  void  receive02(Object msg)
   {

      //把消息打印出来
      log.info(msg);
   }
}

 测试发送消息

@Controller
@RequestMapping("/user")
public  class  UserController
{
   @Autowired   
   private   MQSender  mqSender;
   
   @RequestMapping("/mq/direct01")
   @ResponseBody 
   public  void  mq01()
   {
       mqSender.send01("Hello");   
   }

   public  void  mq02("/mq/direct02")
   {
       mqSender.send02("World");    
   }
}

topic模式:其实也是路由key,只不过为了方便管理路由key(也就是说不再是一个route key对应一个队列,而是一组route key对应一个队列),用了通配符*和#,*是匹配一个词(一个单词而不是一个字母),#是匹配0个或多个

rabbitmq_第9张图片

当一个消息携带的路由keyroute key 是quick.orange.rabbit时,那这个消息既符合1也符合2,所以会被发送给两个队列

当一个消息携带的路由keyroute key 是lazy.orange.elephant时,那这个消息既符合1也符合3,所以也会被发送给两个队列

不符合1,2,3那这条消息就会被抛弃

@Configuration
public  class   RabbitMQTopicConfig
{
    @Bean
    public  Queue    queue01()
    {
        return   new   Queue("queue01");//队列名称就叫queue,消息持久化

    }

    @Bean
    public  Queue    queue02()
    {
        return   new   Queue("queue02");//队列名称就叫queue,消息持久化

    }

    //定义交换机
    pubcli  TopicExchange  topicExchange()
    {
       return  new  TopicExchange("topicExchange");
    }

    @Bean  //绑定队列到交换机,需要带上路由键route key
    public    Binding  binding01()
    {
       return   BindingBuilder.bind(queue01()).to(topicExchange()).with("#.queue.#");
    }

    @Bean  //绑定队列到交换机,需要带上路由键route key
    public    Binding  binding02()
    {
       return   BindingBuilder.bind(queue02()).to(topicExchange()).with("*.queue.#");
    }
}

消息发送方:发送对象

@Service
@Slf4j
public   class MQSender
{
   @Autowired
   private   RabbitTemplate  rabbitTemplate;
 
   public  void  send01(Object msg)
   {

      //发送消息之前(发送的是一个对象),先把消息打印出来
      log.info(msg);
      
     //发送消息到交换机里面
      rabbitTemplate.convertAndSend("topicExchange","queue.red.message",msg); 
      
   }

   public  void  send02(Object msg)
   {

      //发送消息之前(发送的是一个对象),先把消息打印出来
      log.info(msg);
      
     //发送消息到交换机里面
      rabbitTemplate.convertAndSend("topicExchange","message.queue.green.abc",msg); 
      
   }
}

消息接收方:消费者

@Service
@Slf4j
public   class MQReceiver
{

   @RabbitListener(queue="queue01")  //监听叫queue的这个队列
   public  void  receive01(Object msg)
   {

      //把消息打印出来
      log.info(msg);
   }

   @RabbitListener(queue="queue02")  //监听叫queue的这个队列
   public  void  receive02(Object msg)
   {

      //把消息打印出来
      log.info(msg);
   }
}

 测试发送消息

@Controller
@RequestMapping("/user")
public  class  UserController
{
   @Autowired   
   private   MQSender  mqSender;
   
   @RequestMapping("/mq/topic01")
   @ResponseBody 
   public  void  mq01()
   {
       mqSender.send01("Hello");   
   }

   public  void  mq02("/mq/topic02")
   {
       mqSender.send02("World");    
   }
}

header模式基本己经被抛弃了

你可能感兴趣的:(后端开发,后端开发)