【 <二> 丹方改良:Spring 时代的 JavaWeb】之 Spring Boot 中的消息队列:使用 RabbitMQ 实现异步处

<前文回顾>

点击此处查看 合集 https://blog.csdn.net/foyodesigner/category_12907601.html?fromshare=blogcolumn&sharetype=blogcolumn&sharerId=12907601&sharerefer=PC&sharesource=FoyoDesigner&sharefrom=from_link

<今日更新>

一、开篇整活儿

今儿个咱唠唠 Spring Boot 里头的消息队列。这玩意儿吧,说大不大,说小不小,整好了是锦上添花,整不好就是火上浇油。你要是刚入门,那可得悠着点儿,别一上来就整得自己"翻车"了。

二、消息队列是啥玩意儿?

消息队列是系统解耦的一个利器,说白了就是把一些耗时的操作放到队列里头,让系统慢慢处理,不用阻塞主流程。Spring Boot 里头默认就集成了消息队列,用起来贼方便。

1. 消息队列的核心概念

消息队列里头有几个核心概念:生产者 (Producer)、消费者 (Consumer)、队列 (Queue)、交换机(Exchange)。

  • 生产者:就是发送消息的程序。
  • 消费者:就是接收消息的程序。
  • 队列:就是存储消息的地方。
  • 交换机:就是路由消息的地方。

2. RabbitMQ 是啥玩意儿?

RabbitMQ 是一个开源的、高性能的消息队列中间件,支持多种消息协议,比如说 AMQP、STOMP、MQTT 啥的。Spring Boot 里头默认就集成了 RabbitMQ,用起来贼方便。

三、Spring Boot 集成 RabbitMQ

Spring Boot 里头集成 RabbitMQ 很简单,只要加个依赖,配个连接信息就行了。

1. 添加依赖

首先,你得在 pom.xml 里头加个 RabbitMQ 的依赖。

|--------------------------------------------------------------------------------------------------------------------------------------|
| XML Code |
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> |

这段代码里头,spring-boot-starter-amqp 是 Spring Boot 里头的 RabbitMQ 依赖。

2. 配置连接信息

然后,你得在 application.properties 里头配个 RabbitMQ 的连接信息。

|------------------------------------------------------------------------------------------------------------------------|
| Properties Code |
| spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest |

这段代码里头,spring.rabbitmq.host 是 RabbitMQ 的主机地址,spring.rabbitmq.port 是 RabbitMQ 的端口号,spring.rabbitmq.username 是 RabbitMQ 的用户名,spring.rabbitmq.password 是 RabbitMQ 的密码。

3. 使用 RabbitTemplate

最后,你可以在代码里头用 RabbitTemplate 来发送消息。

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java Code |
| @Service public class MyService { @Autowired private RabbitTemplate rabbitTemplate; public void sendMessage(String message) { rabbitTemplate.convertAndSend("myQueue", message); } } |

这段代码里头,RabbitTemplate 是 Spring Boot 里头的一个类,用来发送消息的。

四、Spring Boot 使用 RabbitMQ 实现异步处理

Spring Boot 里头使用 RabbitMQ 实现异步处理很简单,只要加个注解就行了。

1. 定义队列

首先,你得定义一个队列,用 @Bean 注解标记。

|--------------------------------------------------------------------------------------------------------------|
| Java Code |
| @Configuration public class RabbitMQConfig { @Bean public Queue myQueue() { return new Queue("myQueue"); } } |

这段代码里头,myQueue 方法定义了一个队列,名字叫 myQueue。

2. 定义消费者

然后,你得定义一个消费者,用 @RabbitListener 注解标记。

|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java Code |
| @Service public class MyConsumer { @RabbitListener(queues = "myQueue") public void receiveMessage(String message) { System.out.println("收到消息:" + message); } } |

这段代码里头,receiveMessage 方法用 @RabbitListener 注解标记了,表示监听 myQueue 队列。

3. 发送消息

最后,你可以在生产者里头发送消息。

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java Code |
| @Service public class MyService { @Autowired private RabbitTemplate rabbitTemplate; public void sendMessage(String message) { rabbitTemplate.convertAndSend("myQueue", message); } } |

这段代码里头,sendMessage 方法用 RabbitTemplate 发送了一条消息到 myQueue 队列。

五、Spring Boot 使用 RabbitMQ 的坑点

1. 消息丢失

RabbitMQ 里头,消息可能会丢失。你要是没处理好,那消息可就没了。

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java Code |
| @Service public class MyService { @Autowired private RabbitTemplate rabbitTemplate; public void sendMessage(String message) { rabbitTemplate.convertAndSend("myQueue", message, new MessagePostProcessor() { @Override public Message postProcessMessage(Message message) throws AmqpException { message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT); return message; } }); } } |

这段代码里头,setDeliveryMode(MessageDeliveryMode.PERSISTENT) 表示消息持久化,避免消息丢失。

2. 消息重复

RabbitMQ 里头,消息可能会重复。你要是没处理好,那消息可就重复了。

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java Code |
| @Service public class MyConsumer { @RabbitListener(queues = "myQueue") public void receiveMessage(String message, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) throws IOException { System.out.println("收到消息:" + message); channel.basicAck(deliveryTag, false); } } |

这段代码里头,basicAck(deliveryTag, false) 表示手动确认消息,避免消息重复。

3. 消息堆积

RabbitMQ 里头,消息可能会堆积。你要是没处理好,那消息可就堆积了。

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Java Code |
| @Configuration public class RabbitMQConfig { @Bean public Queue myQueue() { return new Queue("myQueue", true, false, false, new HashMap<String, Object>() {{ put("x-max-length", 10000); }}); } } |

这段代码里头,x-max-length 表示队列的最大长度,避免消息堆积。

专有名词解释

  1. 消息队列:系统解耦的一个利器,把一些耗时的操作放到队列里头,让系统慢慢处理。
  2. 生产者:发送消息的程序。
  3. 消费者:接收消息的程序。
  4. 队列:存储消息的地方。
  5. 交换机:路由消息的地方。
  6. RabbitMQ:一个开源的、高性能的消息队列中间件,支持多种消息协议。
  7. RabbitTemplate:Spring Boot 里头的一个类,用来发送消息的。
  8. @RabbitListener:Spring Boot 里头的一个注解,用来监听队列。
  9. MessagePostProcessor:Spring Boot 里头的一个接口,用来处理消息。
  10. MessageDeliveryMode:Spring Boot 里头的一个枚举,用来设置消息的传递模式。
  11. AmqpHeaders.DELIVERY_TAG:Spring Boot 里头的一个常量,用来获取消息的投递标签。
  12. Channel:RabbitMQ 里头的一个接口,用来操作队列。
  13. x-max-length:RabbitMQ 里头的一个参数,用来设置队列的最大长度。

写在最后

身为一个中古程序猿,我有很多自己想做的事情,比如埋头苦干手搓一个低代码数据库设计平台(目前只针对写java的朋友),已经在找朋友内测了,比如很喜欢帮身边的朋友看看简历,讲讲面试技巧,毕竟工作这么多年,也做到过高管,有很多面人经历,意见还算有用,大家基本都能拿到想要的offer...

我深刻意识到,能自由做自己喜欢的事情是有多么不容易,又是多么有成就感。所以我拉了两三个志同道合的好友,开了一间公司,继续朝着"自由"的目标前进。

当下呢,我们希望有更多的朋友能够参与到产品的测试中来,体验并且给出更好的建议。未来可能会在博客po更多关于我们产品的内容,包括使用场景、说明、课程等,希望能对大家有所帮助。

另外,想整个花活儿,每天花个1-2小时,来帮助我素未谋面的老朋友们看看简历 ,提提意见啥的,纯属为爱发电。我在线时间不固定,但是不要米,咱就别要自行车儿了呗~如果您有兴趣,可以点击文章底部卡片一起交流(人工回复,比较慢,请担待)。

最后,请大家持续关注我们的博客,未来还有很多栏目,一起发掘~!

相关推荐
在京奋斗者1 小时前
spring boot自动装配原理
java·spring boot·spring
明天不下雨(牛客同名)4 小时前
为什么 ThreadLocalMap 的 key 是弱引用 value是强引用
java·jvm·算法
多多*4 小时前
Java设计模式 简单工厂模式 工厂方法模式 抽象工厂模式 模版工厂模式 模式对比
java·linux·运维·服务器·stm32·单片机·嵌入式硬件
胡图蛋.6 小时前
Spring Boot 支持哪些日志框架?推荐和默认的日志框架是哪个?
java·spring boot·后端
牛马baby6 小时前
Java高频面试之并发编程-01
java·开发语言·面试
小小大侠客6 小时前
将eclipse中的web项目导入idea
java·eclipse·intellij-idea
不再幻想,脚踏实地7 小时前
MySQL(一)
java·数据库·mysql
吃海鲜的骆驼7 小时前
SpringBoot详细教程(持续更新中...)
java·spring boot·后端
迷雾骑士7 小时前
SpringBoot中WebMvcConfigurer注册多个拦截器(addInterceptors)时的顺序问题(二)
java·spring boot·后端·interceptor
别来无恙✲7 小时前
Mybatis源码分析
java·源码分析