SpringBoot 系列:RabbitMq 讲解与示例
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</grou Java 开源项目【ali1024.coding.net/public/P7/Java/git】 pId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
其中在 common 包下,是 swagger 的配置文件。
package com.yanger.rabbitmq.common;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
@description Swagger 插件
@author 杨号
@date 2018 年 9 月 14 日
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
// 当前包路径
.apis(RequestHandlerSelectors.basePackage("com.yanger"))
.paths(PathSelectors.any()).build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
// 页面标题
.title("yblog Swagger2 API 接口").description("yblog API 接口文档")
.termsOfServiceUrl("https://github.com/imyanger")
// 创建人
.contact(new Contact("yanger", "https://github.com/imyanger/", "550799932@qq.com")).version("1.0")
.build();
}
}
这样我们的 SpringBoot + RabbitMq 环境就已经搭建完毕了,下面我们来具体探讨 4 中交换机策略。
1.Direct Exchange
Direct Exchange 是 RabbitMQ 默认的交换机模式,也是最简单的模式,根据 key 全文匹配去寻找队列。
定义队列及路由匹配规则,分别为 direct_queue_1 和 direct_queue_2
定义消费者,也就是消息接收者,我们这里发送者和接收在一个项目中,而实际生产中,可能不在一个项目中,但是效果都是一样的。@RabbitListener 声明监听,并设置 queues 属性表明监听的队列。
然后是生产者,也就是消息发送者,这里发送消息的路由和队列的规则完全匹配,也为 direct_queue_1 和 direct_queue_2
最后是测试类,我们创建了 Controller 进行接口调用,项目启动后,因为是 get 请求,可以浏览器地址栏调用,也可以使用 swagger 工具。
然后启动项目,在[http://localhost:19031/swagger-ui.html](()下,我们已经可以看到该接口了。输入参数进行测试,后面的测试也是相同,将不在累述。
我们可以看到控制台的输出,和 direct 交换机策略介绍的一样,direct_queue_1 接收接受了指向 direct_queue_1 路由的的消息,direct_queue_2 接收接受了指向 direct_queue_2 路由的的消息。
2.Topic Exchange
按规则转发消息(最灵活) 转发消息主要是根据通配符。 在这种交换机下,队列和交换机的绑定会定义一种路由模式,那么,通配符就要在这种路由模式和路由键之间匹配后交换机才能转发消息。
路由键必须是一串字符,用句号(.) 隔开,路由模式必须包含一个 星号(*),主要用于匹配路由键指定位置的一个单词, 井号(#)就表示相当于一个或者多个单词。
下面是配置文件,队列 1.2.3 绑定了 topic 交换机,且路由规则分别定义为 routingkey.#、#.topic 和 #。
package com.yanger.rabbitmq.topic;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class TopicConfig {
/*
按规则转发消息(最灵活) 转发消息主要是根据通配符。 在这种交换机下,队列和交换机的绑定会定义一种路由模式,那么,通配符就要在这种路由模式和路由键之间匹配后交换机才能转发消息。
路由键必须是一串字符,用句号(.) 隔开,
路由模式必须包含一个 星号(*),主要用于匹配路由键指定位置的一个单词, 井号(#)就表示相当于一个或者多个单词
*/
public static final String QUEUE1 = "topic_queue_1";
public static final String QUEUE2 = "topic_queue_2";
public static final String QUEUE3 = "topic_queue_3";
@Bean
public Queue topicQueue1() {
return new Queue(QUEUE1);
}
@Bean
public Queue topicQueue2() {
return new Queue(QUEUE2);
}
@Bean
public Queue topicQueue3() {
return new Queue(QUEUE3);
}
// topic 策略的交换机
@Bean
public TopicExchange topicExchange(){
return new TopicExchange("topic");
}
// 绑定 topicQueue1 到 topic 交换机上,并指定路由匹配规则为 routingkey.#,即路由以 routingkey.开头的消息都将被 topicQueue1 接收
@Bean
public Binding topicBinding1(){
return BindingBuilder.bind(topicQueue1()).to(topicExchange()).with("routingkey.#");
}
// 绑定 topicQueue2 到 topic 交换机上,并指定路由匹配规则为 #.topic,即路由以.topic 结尾的消息都将被 topicQueue2 接收
@Bean
public Binding topicBinding2(){
return BindingBuilder.bind(topicQueue2()).to(topicExchange()).with("#.topic");
}
// 绑定 topicQueue3 到 topic 交换机上,并指定路由匹配规则为路由 #,即任意路由消息都将被 topicQueue3 接收
@Bean
public Binding topicBinding3(){
return BindingBuilder.bind(topicQueue3()).to(topicExchange()).with("#");
}
}
下面是消费者,主要是对规则及接收的消息进行打印输出。
生产者,向 topic 交换机上路由 routingkey.all、all.topic、all.all 发送消息。
进行测试,最终结果,可以发现绑定 #规则的队列接收了该交换机上所有路由的消息,routingkey.#则接收该交换机上 routingkey.开头的,#.topic 则接收所有.topic 结尾的。可以将 all 换成一个或多个字符,测试结果是一样的。
3. Headers Exchange
设置 header attribute 参数类型的交换机,相较于 direct 和 topic 固定地使用 routing_key , headers 则是一个自定义匹配规则的类型. 在队列与交换器绑定时, 会设定一组键值对规则, 消息中也包 《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》开源 括一组键值对( headers 属性), 当这些键值对有一对, 或全部匹配时, 消息被投送到对应队列。
header 策略配置文件,将 headers_queue_1 和 headers_queue_2 分别绑定到 headers 交换机上,并指定匹配规则,whereAll 要求 header 中属性全部都匹配,而 whereAny 允许有任意一个属性匹配即可。
package com.yanger.rabbitmq.headers;
import java.util.HashMap;
import java.util.Map;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.HeadersExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HeadersConfig {
/**
headers 是一个自定义匹配规则的类型,在队列与交换器绑定时,会设定一组键值对规则,
消息中也包括一组键值对( headers 属性), 当这些键值对有一对, 或全部匹配时, 消息被投送到对应队列
惊喜
最后还准备了一套上面资料对应的面试题(有答案哦)和面试时的高频面试算法题(如果面试准备时间不够,那么集中把这些算法题做完即可,命中率高达 85%+)
评论