基础使用
前期准备
创建一个服务名为RabbitMQ
的Spring boot
项目
xml配置
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.14</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<nacos.context>2.1.0-RC</nacos.context>
<!-- <swagger.ui>2.9.2</swagger.ui> -->
<swagger.ui>3.0.0</swagger.ui>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.18.26</lombok.version>
<mysql.version>5.1.47</mysql.version>
<druid.version>1.1.16</druid.version>
<druid.spring.boot.starter.version>1.1.10</druid.spring.boot.starter.version>
<mapper.version>4.1.5</mapper.version>
<mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
<mysql.connector.version>5.1.47</mysql.connector.version>
<hutool.version>5.2.3</hutool.version>
<mybatis.plus.boot.starter.version>3.2.0</mybatis.plus.boot.starter.version>
<guava.version>23.0</guava.version>
<canal.client.version>1.1.0</canal.client.version>
<redission.version>3.19.1</redission.version>
</properties>
<dependencies>
<!--基于AMQP协议的消息中间件框架-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!-- SpringBoot通用依赖模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 通用基础配置 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
<!-- swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>${swagger.ui}</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<!-- 通用基础配置junit/devtools/test/log4j/lombok/hutool -->
<!-- hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
</dependencies>
主要使用的是
spring-boot-starter-amqp
AMQP协议的消息中间件框架<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>
yml配置
server:
port: 9999
spring:
application:
name: rabbit-mq-learn
swagger2:
enabled: true
config
@Configuration
public class SwaggerConfig {
@Value("${spring.swagger2.enabled:false}")
private Boolean enabled;
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(enabled)
//通过.select()方法,去配置扫描接口
.select()
.apis(RequestHandlerSelectors.basePackage("org.whn.controller"))
// 配置如何通过path过滤
.paths(PathSelectors.any())
.build();
}
Contact contact = new Contact("whn","https://blog.csdn.net/","1470918223@qq.com");
//配置Swagger 信息 = ApiInfo
public ApiInfo apiInfo() {
return new ApiInfoBuilder()
// .contact(contact)
.title("springboot利用swagger2构建api接口文档 "+"\t"+ DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now()))
.description("springboot+redis整合")
.version("1.0")
.build();
}
}
测试Controller
@ApiModel(value = "test Controller",description = "测试controller")
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("/")
public String getTest(){
return "controller test";
}
}
生产消费处理
RabbitMQ是一个消息代理:它接受和转发消息。 你可以把它想象成一个邮局:当你把邮件放在邮箱里时,你可以确定邮差先生最终会把邮件发送给你的收件人。
在这个比喻中,RabbitMQ是邮政信箱,邮局和邮递员。
RabbitMQ与邮局的主要区别是它不处理纸张,而是接受,存储和转发数据消息的二进制数据块。
- P(producer/ publisher):生产者,一个发送消息的用户应用程序。
- C(consumer):消费者,消费和接收有类似的意思,消费者是一个主要用来等待接收消息的用户应用程序
- 队列(红色区域):rabbitmq内部类似于邮箱的一个概念。虽然消息流经rabbitmq和你的应用程序,但是它们只能存储在队列中。
- 队列只受主机的内存和磁盘限制,实质上是一个大的消息缓冲区。许多生产者可以发送消息到一个队列,许多消费者可以尝试从一个队列接收数据。总之:
- 生产者将消息发送到队列,消费者从队列中获取消息,队列是存储消息的缓冲区。
- 我们将用Java编写两个程序;发送单个消息的生产者,以及接收消息并将其打印出来的消费者。
- 我们将详细介绍Java API中的一些细节,这是一个消息传递的“Hello World”。
- 我们将调用我们的消息发布者(发送者)Send和我们的消息消费者(接收者)Recv。
- 发布者将连接到RabbitMQ,发送一条消息,然后退出。
接下来我们使用简单工作模型演示一下mq的基础使用
-
创建连接工具类
public class ConnectionUtil { /** * rabbitMq 链接地址 */ private static final String HOST = "43.138.25.182"; /** * rabbitMq 连接端口 */ private static final int PORT = 5672; /** * 连接用户名 */ private static final String USER = "admin"; /** * 连接用户密码 */ private static final String PASSWORD = "123456"; public static Connection getConnection() throws Exception { //定义连接工厂 ConnectionFactory factory = new ConnectionFactory(); //设置服务地址 factory.setHost(HOST); //端口 factory.setPort(PORT); //设置账号信息,用户名、密码 factory.setUsername(USER); factory.setPassword(PASSWORD); // 通过工程获取连接 return factory.newConnection(); } }
-
创建生产者
/ ** * 声明队列 * @param queue队列名称 * @param durable 如果我们声明一个持久队列,则为true(该队列将在服务器重启后继续存在) * @param Exclusive 如果我们声明一个排他队列,则为true(仅限此连接) * @param autoDelete 如果我们声明一个自动删除队列,则为true(服务器将在不再使用它时将其删除) * @param arguments 参数队列的其他属性(构造参数) * @return 一个声明确认方法来指示队列已成功声明 * / Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,Map<String, Object> arguments) throws IOException;
public class Producter { private final static String QUEUE_NAME = "simple_queue"; public static void main(String[] argv) throws Exception { // 获取到连接 Connection connection = ConnectionUtil.getConnection(); // 从连接中创建通道,使用通道才能完成消息相关的操作 Channel channel = connection.createChannel(); // 声明(创建)队列 channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 消息内容 String message = "Hello World!"; // 向指定的队列中发送消息 channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); System.out.println(" [x] Sent '" + message + "'"); //关闭通道和连接 channel.close(); connection.close(); } }
-
创建消费者
public class Consumer { private final static String QUEUE_NAME = "simple_queue"; public static void main(String[] argv) throws Exception { // 获取到连接 Connection connection = ConnectionUtil.getConnection(); // 创建通道 Channel channel = connection.createChannel(); // 声明队列 channel.queueDeclare(QUEUE_NAME, false, false, false, null); // 定义队列的消费者 DefaultConsumer consumer = new DefaultConsumer(channel) { // 获取消息,并且处理,这个方法类似事件监听,如果有消息的时候,会被自动调用 @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { // body 即消息体 String msg = new String(body); System.out.println(" [x] received : " + msg + "!"); } }; // 监听队列,第二个参数:是否自动进行消息确认。 channel.basicConsume(QUEUE_NAME, true, consumer); } }
我们发现,消费者已经获取了消息,但是程序没有停止,一直在监听队列中是否有新的消息。一旦有新的消息进入队列,就会立即打印.