开门见山(文末附有消息队列的几个基本概念)
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使用