Spring Boot 之 RabbitMQ 消息队列中间件的三种模式

开门见山(文末附有消息队列的几个基本概念)

1、直接模式( Direct)模式 

直白的说就是一对一,生产者对应唯一的消费者(当然同一个消费者可以开启多个服务)。

虽然使用了自带的交换器(Exchange),但使用的是默认的“”空字符串交换器,

也相当于直接跨过交换器到达消息队列,也是称为直接模式的原因(猜的)

生产者代码:

  @Autowired
    private RabbitTemplate rabbitTemplate;

    /*
        普通模式:
     */
    @Test
    public void SendMag(){
        rabbitTemplate.convertAndSend("Not_Copy1","直接模式测试");
    }

RabbitMQ管理器:

 

消费者代码:

服务一
@Component @RabbitListener(queues
= "Not_Copy1") public class Customer1 { @RabbitHandler public void getMsg(String msg){ System.out.println("11111Not_Copy1:"+msg); } }

服务二
@Component
@RabbitListener(queues = "Not_Copy1")
public class Customer1 {

    @RabbitHandler
    public void getMsg(String msg){
        System.out.println("22222Not_Copy1:"+msg);
    }
}
服务三
@Component @RabbitListener(queues
= "Not_Copy1") public class Customer1 { @RabbitHandler public void getMsg(String msg){ System.out.println("33333Not_Copy1:"+msg); } }

消息连发三次

结果:

服务一:11111Not_Copy1:直接模式测试

服务二:22222Not_Copy1:直接模式测试

服务三:33333Not_Copy1:直接模式测试

证明存在着默认的负载均衡。

 

2、分裂模式(Fanout)模式

直白的说就是一对多,一个生产者对应多个消费者(当然同一个消费者可以开启多个服务)。

使用了自定义的交换器(Exchange),由交换器分发给与当前交换器相 关联的消息队列,

就像发牌员发牌一样。

生产者代码:

  @Autowired
    private RabbitTemplate rabbitTemplate;
   /**
     * 分裂模式  交换器 Distributor
     */
    @Test
    public void SendMag1(){
        rabbitTemplate.convertAndSend("Distributor","","分裂模式测试");
    }

RabbitMQ管理器:

交换器 Distributor 分配了三个消息队列,因为是分裂模式是以Type选  fanout

消费者代码:

消费者一

@Component
@RabbitListener(queues = "Not_Copy1")
public class Customer1 {

    @RabbitHandler
    public void getMsg(String msg){
        System.out.println("Not_Copy1:"+msg);
    }
}
消费者二
@Component
@RabbitListener(queues = "Not_Copy2")
public class Customer2 {

    @RabbitHandler
    public void getMsg(String msg){
        System.out.println("Not_Copy2:"+msg);
    }
}

 消费者三

@Component
@RabbitListener(queues = "Not_Copy3")
public class Customer3 {

    @RabbitHandler
    public void getMsg(String msg){
        System.out.println("Not_Copy3:"+msg);
    }
}

消息发送一遍

结果:

消费者一:Not_Copy1:分裂模式测试

消费者二:Not_Copy2:分裂模式测试

消费者三:Not_Copy3:分裂模式测试

注意:每个消费者是一个类(Customer1,Customer2,Customer3),而不是三个消费者写在一个个类中。

 

3、主题模式(Topic)

直白的说主题模式也是一对多,只不过在分裂模式模式的基础上添加了规则或者说主题,

交换器按照规则或者说按照主题下发,符合规则或者说主题的才下发

生产者代码:

  @Autowired
    private RabbitTemplate rabbitTemplate;/*
       主题模式
    */
    @Test
    public void SendMag1(){
        rabbitTemplate.convertAndSend("Distributor2","good.abc","主题模式测试");
    }
   @Test
    public void SendMag2(){
        rabbitTemplate.convertAndSend("Distributor2","good.abc.log","主题模式测试");
    }
   @Test
    public void SendMag3(){
        rabbitTemplate.convertAndSend("Distributor2","good.log","主题模式测试");
    }

 

 RabbitMQ管理器:

交换器Distributor2 分配了三个消息队列,并为各其配置了主题  因为是分裂模式是以Type选  topic

结果:

生产者:SendMag1(),主题:good.abc ,

对应消费者:Not_Copy1:主题模式测试

 

生产者:  SendMag2() ,主题:good.abc.log ,

对应消费者:Not_Copy1:主题模式测试

      Not_Copy2:主题模式测试

 

生产者:  SendMag3() ,主题:good.log ,     

对应消费者:Not_Copy1:主题模式测试

      Not_Copy2:主题模式测试

      Not_Copy3:主题模式测试

 

通过这三个主题大家应该已经熟悉了主题模式的应用。

基本概念:

RabbitMQ Server: 也叫broker server,它是一种传输服务。 他的角色就是维护一条 从Producer到Consumer的路线,保证数据能够按照指定的方式进行传输。


Producer: 消息生产者,如图A、B、C,数据的发送方。消息生产者连接RabbitMQ服 务器然后将消息投递到Exchange。


Consumer:消息消费者,如图1、2、3,数据的接收方。消息消费者订阅队列, RabbitMQ将Queue中的消息发送到消息消费者。

Exchange:生产者将消息发送到Exchange(交换器),由Exchange将消息路由到一个 或多个Queue中(或者丢弃)。Exchange并不存储消息。RabbitMQ中的Exchange有 direct、fanout、topic、headers四种类型,每种类型对应不同的路由规则。


Queue:(队列)是RabbitMQ的内部对象,用于存储消息。消息消费者就是通过订阅 队列来获取消息的,RabbitMQ中的消息都只能存储在Queue中,生产者生产消息并终 投递到Queue中,消费者可以从Queue中获取消息并消费。多个消费者可以订阅同一个 Queue,这时Queue中的消息会被平均分摊给多个消费者进行处理,而不是每个消费者 都收到所有的消息并处理。


RoutingKey:生产者在将消息发送给Exchange的时候,一般会指定一个routing key, 来指定这个消息的路由规则,而这个routing key需要与Exchange Type及binding key联 合使用才能终生效。在Exchange Type与binding key固定的情况下(在正常使用时一 般这些内容都是固定配置好的),我们的生产者就可以在发送消息给Exchange时,通过 指定routing key来决定消息流向哪里。RabbitMQ为routing key设定的长度限制为255 bytes。

Connection: (连接):Producer和Consumer都是通过TCP连接到RabbitMQ Server 的。以后我们可以看到,程序的起始处就是建立这个TCP连接。


Channels: (信道):它建立在上述的TCP连接中。数据流动都是在Channel中进行 的。也就是说,一般情况是程序起始建立TCP连接,第二步就是建立这个Channel。


VirtualHost:权限控制的基本单位,一个VirtualHost里面有若干Exchange和 MessageQueue,以及指定被哪些user使用

 

posted @ 2019-07-19 17:12  NOT_COPY  阅读(582)  评论(0编辑  收藏  举报