当前位置: 首页 > news >正文

【 <二> 丹方改良: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小时,来帮助我素未谋面的老朋友们看看简历,提提意见啥的,纯属为爱发电。我在线时间不固定,但是不要米,咱就别要自行车儿了呗~如果您有兴趣,可以点击文章底部卡片一起交流(人工回复,比较慢,请担待)。

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

相关文章:

  • C++ STL常用算法之常用算术生成算法
  • 【区块链安全 | 第十四篇】类型之值类型(一)
  • ShuffleNet、MobileNet 和 EfficientNet的区别
  • 探索OCR的第二个方案:EasyOCR
  • 小智机器人关键函数解析,Application::MainLoop() 用于持续监听事件组中的事件,并根据不同的事件触发相应的操作
  • Android在KSP中简单使用Room
  • Vue.js的多个组件过渡:实现组件的动态切换
  • 互联网的组成
  • C语言信号量使用案例
  • 每日小积累day1
  • TDengine tar.gz和docker两种方式安装和卸载
  • 【蓝桥杯速成】| 16.完全背包组合|排序
  • Rollup系列之安装和入门
  • MQTT之重复消息(6、在项目中遇到的问题)
  • Pandas **Series**
  • 传统策略梯度方法的弊端与PPO的改进:稳定性与样本效率的提升
  • 【干货】前端实现文件保存总结
  • rce操作
  • 唤起“堆”的回忆
  • 基于自定义注解+反射+AOP+Redis的通用开关设计:在投行交易与风控系统的落地实践