消息中间件:
ActiveMQ,RabbitMQ,Kafka等都是常见的消息中间件,安全性从高到低,速度从低到高,Kafka在大数据中使用较多,RabbitMQ在银行系统中使用较多。主要应用在异步解耦、消息缓冲等场景中。
RabbitMQ简介:
由Erlang语言开发,实现AMQP(Advanced Message Queuing Protocol)的一种消息中间件。支持多种客户端,例如:Python、Ruby、.NET、Java、JMS、C、PHP等。
springboot、springcloud、docker学习目录:【传送门】
结构:
来自百度百科:
提到消息中间件,我们常听到的是:消息生产者、消费者、队列。如图,RabbitMQ多了一个Exchange交换器,Exchange位于消息生产者和队列之间。
相关名词:
-
Producer: 消息生产者,图中最左边。将消息发送到Exchange中。
-
Consumer:消息消费者,图中最右边。订阅队列中的消息。
-
RabbitMQ Server:传输服务,维护着生产者到消费者之间的线路,保证消息按照指定的方式传输。
-
Exchange:交换器,将接收到的producer消息路由到指定队列(一或多个)。具有direct、fanout、topic、headers四种类型,每种类型对应不同的路由规则
-
Queue:队列,用于存放Exchange路由过来的消息,consumer从队列中订阅消息。
-
RoutingKey:路由规则,生产者发送消息到Exchange时指定,Exchange根据路由规则将消息发送到哪一个Queue中存储。
集成RabbitMQ:
1、docker安装RabbitMQ:
# 1、获取镜像
docker pull rabbitmq:management
# 2、创建容器
docker run ‐di ‐‐name=tensquare_rabbitmq ‐p 5671:5617 ‐p 5672:5672 ‐p 4369:4369 ‐p 15671:15671 ‐p 15672:15672 ‐p 25672:25672 rabbitmq:management
监视画面:http://192.168.25.133:15672默认用户名、密码:guest
2、pom依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
3、application配置:
server:
port: 8099
spring:
rabbitmq:
host: 192.168.25.133
port: 5672
username: guest
password: guest
直接模式(Direct):
1、队列配置:
@Configuration
public class DirectConfig {
@Bean
public Queue helloQueue(){
return new Queue("hello");
}
}
亦可在15672监视画面中配置。
2、Producer:
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 直接模式 最简单的使用
* 一个消息只会有一个消费者,
*/
@Test
public void testSend(){
// 多个消费者只有一个消费者接收到消息
rabbitTemplate.convertAndSend("hello","直接模式测试");
// 多个接收者 均匀的分布到消费者中
/*for (int i = 0; i < 10; i++) {
rabbitTemplate.convertAndSend("hello","直接模式测试 :" + i);
}*/
}
3、consumer:
@Component
@RabbitListener(queues = "hello")
public class DirectCcustomer01 {
@RabbitHandler
public void showMessage(String message){
System.out.println("DirectCcustomer01 >>>hello>>>接收到消息:"+message);
}
}
@Component
@RabbitListener(queues = "hello")
public class DirectCcustomer02 {
@RabbitHandler
public void showMessage(String message){
System.out.println("DirectCcustomer02 >>>hello>>>接收到消息:"+message);
}
}
4、测试:
-
发送一次:多个消费者只有一个消费者可以接收。
-
发送多次:多个消费者均匀消费。
分列模式(Fanout):
1、队列配置:
@Configuration
public class FanoutConfig {
/*********************** 定义队列 start ************************/
@Bean
public Queue fanoutA() {
return new Queue("fanout.a");
}
fanoutB、fanoutC 省略... 参看fanoutA 或 下载代码
/*********************** 定义队列 end ************************/
/**
* 分列式 交换器
* 名称:fanoutExchange
*/
@Bean
FanoutExchange fanoutExchange() {
return new FanoutExchange("fanoutExchange");
}
/****************** 队列绑定交换机 start ********************/
// fanoutA 与 fanoutExchange 绑定
@Bean
public Binding bindingExchangeWithA() {
return BindingBuilder.bind(fanoutA()).to(fanoutExchange());
}
fanoutB、fanoutC 绑定省略... 参看fanoutA 或 下载代码
/****************** 队列绑定交换机 end ********************/
}
2、Producer:
/**
* 分列模式 -- 将消息一次发给多个队列
* 不需要 routingKey 规则匹配 直接模式的加强版
*/
@Test
public void testSendFanout(){
rabbitTemplate.convertAndSend("fanoutExchange","", "分列模式发送的消息");
}
3、consumer:
@Component
@RabbitListener(queues = "fanout.a")
public class FanoutConsumerA {
@RabbitHandler
public void showMessage(String message){
System.out.println(">>>FanoutConsumerA >>>fanout.a>>>接收到消息:"+message);
}
}
FanoutConsumerB 、C省略...参看FanoutConsumerA 或下载代码。
4、测试:
发送一次消息,FanoutConsumerA 、B、C都可以接收到消息。
订阅模式(Topic):
1、队列配置:
注意:"#"代表0个、一个或多个词、"*"代表一个词,"."分隔。
2、Producer:
/**
* 主题模式
*/
@Test
public void testSendTopic1(){
rabbitTemplate.convertAndSend("topicExchange","topic.coolron","主题模式");
}
@Test
public void testSendTopic2(){
rabbitTemplate.convertAndSend("topicExchange","topic.cool.ron","主题模式");
}
@Test
public void testSendTopic3(){
rabbitTemplate.convertAndSend("topicExchange","topic.ron","主题模式");
}
3、consumer:
@Component
@RabbitListener(queues = "topic.a")
public class TopicCustomerA {
@RabbitHandler
public void showMessage(String message){
System.out.println("TopicCustomerA>>>topic.a>>>接收到消息:"+message);
}
}
TopicCustomerB 、C省略...参看FanoutConsumerA 或下载代码。
4、测试结果:
-
testSendTopic1:三个consumer都可以订阅到消息。
-
testSendTopic2:只有TopicCustomerB订阅到消息。
-
testSendTopic3:TopicCustomerB、C订阅到消息。
总结:
1、一条消息,直接模式只能一个消费者订阅、分列模式可多个消费者订阅、topic模式根据路由规则匹配订阅。
2、Exchange位于producer和queue之间。
3、Exchange根据匹配规则将消息路由到对应的Queue中存储。
4、routingKey,"#"代表0个、一个或多个、"*"代表一个词。上文中"topic."会匹配到B、C,因为“”代表一个词。“topic”只会匹配到B。
代码地址:
https://gitee.com/cpla026/springboot-account2/tree/master/springboot2_parent/rabbitmq_demo
个人学习分享
更多 springboot、springcloud、docker 文章,关注微信公账号吧: