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

Spring Boot 集成 ActiveMQ 实现异步消息通信(一)

一、引言

{"type":"load_by_key","key":"auto_image_0_0","image_type":"search"}

在当今分布式系统盛行的软件开发领域,系统的架构复杂度与日俱增,如何高效地处理各个组件之间的通信成为了关键挑战。异步消息通信作为一种强大的解决方案,正逐渐成为构建高性能、高可扩展性系统的基石。

异步消息通信的核心优势在于它能够有效地解耦系统组件。在传统的同步通信模式下,组件之间的调用往往是紧密耦合的,一个组件的状态变化或者性能问题可能会直接影响到其他组件,甚至导致整个系统的不稳定。而异步消息通信通过引入消息队列这一中间层,将消息的发送者和接收者分离,使得它们可以独立地进行演进和扩展。例如,在一个电商系统中,订单创建、库存更新和物流通知等功能模块可以通过异步消息通信实现解耦。当用户创建订单时,订单信息被发送到消息队列,库存系统和物流系统可以根据自身的节奏从队列中获取消息并进行处理,而无需等待彼此的操作完成。这样一来,系统的各个部分可以更加灵活地进行升级和维护,不会因为某个模块的变化而影响到其他模块的正常运行。

异步消息通信还能显著提升系统的性能和可靠性。在高并发场景下,同步通信容易导致线程阻塞和资源竞争,从而降低系统的响应速度。而异步通信允许系统在发送消息后立即返回,继续处理其他任务,大大提高了系统的吞吐量和响应能力。同时,消息队列的持久化机制可以确保即使在系统出现故障时,消息也不会丢失,从而保证了系统的可靠性。

在众多实现异步消息通信的技术方案中,Spring Boot 与 ActiveMQ 的集成脱颖而出,成为了开发者们的热门选择。Spring Boot 作为一款快速开发框架,以其强大的自动配置和依赖管理功能,极大地简化了 Spring 应用的搭建过程,让开发者能够专注于业务逻辑的实现。ActiveMQ 则是一款广泛使用的开源消息代理,它全面支持 JMS(Java Message Service)规范,提供了可靠的消息传递机制,支持多种消息模型和传输协议,能够满足各种复杂的应用场景需求。

通过将 Spring Boot 与 ActiveMQ 集成,开发者可以充分利用两者的优势,轻松构建出高效、可靠的异步消息通信系统。这种集成方式不仅能够帮助企业提升系统的性能和稳定性,还能为业务的快速迭代和创新提供有力支持。在接下来的内容中,我们将详细介绍 Spring Boot 集成 ActiveMQ 实现异步消息通信的具体步骤和应用场景,帮助大家深入理解和掌握这一强大的技术组合。

二、技术背景介绍

(一)Spring Boot

Spring Boot 是由 Pivotal 团队提供的全新框架,它的出现极大地简化了 Spring 应用的初始搭建以及开发过程 。在传统的 Spring 开发中,开发者需要花费大量的时间和精力去进行各种繁琐的配置,例如配置数据源、事务管理器、MVC 框架等,这些配置不仅复杂,而且容易出错。而 Spring Boot 通过引入自动配置(Auto - Configuration)机制,能够根据项目的依赖和配置文件,自动为应用程序创建合理的默认配置。例如,当我们在项目中引入了spring-boot-starter-web依赖时,Spring Boot 会自动配置好 Spring MVC 和嵌入式的 Tomcat 服务器,让我们可以迅速开始编写 Web 接口,无需手动配置 Tomcat 的各种参数以及 Spring MVC 的核心组件。

起步依赖(Starter Dependencies)也是 Spring Boot 的一大特色。它将一组相关的依赖打包在一起,形成一个预配置的依赖集合。以spring-boot-starter-data-jpa为例,当我们引入这个起步依赖时,它会自动引入 Spring Data JPA、Hibernate 以及相关的数据库驱动等一系列依赖,开发者无需逐个查找和添加这些依赖,大大节省了时间和精力,同时也减少了因依赖版本不兼容而导致的问题。

(二)ActiveMQ

ActiveMQ 是 Apache 软件基金会所研发的开放源代码消息中间件,是一个基于 Java 的消息队列,完全支持 JMS1.1 和 J2EE 1.4 规范。它提供了丰富的特性,使其成为异步消息通信的理想选择。

ActiveMQ 支持多种协议,如 TCP、UDP、NIO、SSL、HTTP (S)、VM 等。其中,TCP 协议是最常用的协议之一,它提供了可靠的网络传输,适用于大多数网络环境。例如,在一个分布式系统中,各个服务之间可以通过 TCP 协议与 ActiveMQ 进行通信,确保消息的稳定传输。NIO 协议则适用于高并发场景,当有大量的客户端连接到 Broker 上时,使用 NIO 比使用 TCP 需要更少的线程数量,能够有效提升系统的性能。

在消息模型方面,ActiveMQ 支持队列(Queue)和主题(Topic)两种模型。队列模型基于点对点的通信方式,消息生产者将消息发送到队列中,只有一个消费者可以从队列中获取消息,就像在一个任务分配系统中,任务被发送到队列,每个任务只会被一个工作者获取并处理。而主题模型则是发布 - 订阅模式,消息生产者将消息发布到主题,所有订阅了该主题的消费者都可以收到消息,例如在一个新闻发布系统中,新闻作为消息发布到主题,所有订阅该主题的用户都能收到新闻。

ActiveMQ 还具备强大的消息持久化功能。当消息被发送到 ActiveMQ 后,即使在服务器重启或者出现故障的情况下,通过消息持久化,这些消息也不会丢失。它支持多种持久化方式,如基于文件的 KahaDB 和基于数据库的 JDBC 持久化。KahaDB 具有写入速度快和容易恢复的特点,适合对性能要求较高的场景;而 JDBC 持久化则可以利用数据库的强大功能,确保数据的安全性和一致性,适用于对数据可靠性要求极高的场景。

(三)异步消息通信

异步消息通信是一种在分布式系统中广泛应用的通信模式,它与同步通信有着显著的区别。在同步通信中,客户端发送请求后,会一直阻塞等待服务器的响应,直到收到响应后才会继续执行后续操作。例如,在一个简单的电商系统中,当用户查询商品信息时,客户端向服务器发送查询请求,然后等待服务器返回商品信息,在这个等待过程中,客户端无法进行其他操作。这种方式在网络延迟较高或者服务器负载较大的情况下,会导致客户端响应缓慢,严重影响用户体验。

而异步消息通信则不同,客户端发送消息后,不需要等待消息的处理结果,而是继续执行其他任务。当消息处理完成后,服务器会通过某种方式(如回调函数、消息队列)通知客户端。例如,在一个订单处理系统中,当用户提交订单后,订单信息被发送到消息队列,客户端可以立即返回给用户订单提交成功的提示,而订单的后续处理(如库存检查、支付处理等)则由其他服务从消息队列中获取订单信息并进行处理。这样可以大大提高系统的响应速度和吞吐量,增强系统的并发处理能力。

异步消息通信在分布式系统中有着诸多优势。它能够实现系统组件之间的解耦。在一个复杂的分布式系统中,各个组件之间可能存在着复杂的依赖关系,通过异步消息通信,组件之间只需要关注消息的发送和接收,而不需要了解对方的具体实现细节,从而降低了组件之间的耦合度,使得系统更加灵活和易于维护。异步消息通信还可以实现削峰填谷。在高并发场景下,系统可能会瞬间接收到大量的请求,通过将这些请求放入消息队列,系统可以按照自己的节奏从队列中获取请求并进行处理,避免了因瞬间高负载而导致系统崩溃,保证了系统的稳定性。

三、集成步骤详细讲解

(一)创建 Spring Boot 项目

我们可以借助 IDEA 这个强大的开发工具来创建 Spring Boot 项目。打开 IDEA 后,点击 “New”,再选择 “Project”。在弹出的窗口中,左侧菜单找到 “Spring Initializr”,这里 IDEA 默认使用https://start.spring.io提供的在线模板,所以确保网络畅通。点击 “Next”,进入项目信息填写页面,在这里我们要填写项目的基本信息,比如 Group(通常是公司或组织的域名倒置,像com.example)、Artifact(项目的唯一标识符,例如activemq - integration) ,Type 选择 Maven Project,然后点击 “Next”。接下来,在依赖选择页面,从众多依赖中勾选 “Spring Web”,它能帮助我们快速搭建 Web 应用,为后续的测试和使用提供便利。完成选择后,点击 “Finish”,IDEA 就会自动为我们创建项目并下载相关依赖。

若不想使用 IDEA,也可以通过 Spring Initializr 官网(https://start.spring.io/)来创建项目。在官网页面,同样填写 Group、Artifact 等信息,选择 Spring Boot 版本和所需依赖,然后点击 “Generate”,即可下载一个压缩包,解压后就能得到一个 Spring Boot 项目的基础结构。

(二)添加 ActiveMQ 依赖

创建好项目后,我们要在项目的pom.xml文件中添加 Spring Boot Starter ActiveMQ 依赖,它能帮助我们快速集成 ActiveMQ 到 Spring Boot 项目中。在pom.xml的<dependencies>标签内添加如下代码:

 

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-activemq</artifactId>

</dependency>

添加完依赖后,Maven 会自动下载所需的库文件,这个过程可能需要一些时间,取决于网络状况。下载完成后,我们就可以在项目中使用 ActiveMQ 相关的功能了。

(三)配置 ActiveMQ 连接信息

接下来,我们需要在application.properties或application.yml文件中配置 ActiveMQ 的连接信息。如果使用application.properties,添加以下配置:

 

# ActiveMQ的连接地址,这里假设ActiveMQ运行在本地,端口为61616

spring.activemq.broker-url=tcp://localhost:61616

# 连接ActiveMQ的用户名

spring.activemq.user=admin

# 连接ActiveMQ的密码

spring.activemq.password=admin

要是使用application.yml,配置如下:

 

spring:

activemq:

broker-url: tcp://localhost:61616

user: admin

password: admin

这些配置告诉 Spring Boot 如何连接到 ActiveMQ 服务器,包括服务器的地址、用户名和密码。如果你的 ActiveMQ 服务器有不同的配置,比如运行在不同的主机或端口,或者使用了不同的用户名和密码,记得相应地修改这些配置。

(四)创建消息队列

创建消息队列有两种常见的方式,一种是使用 ActiveMQ Admin Console,另一种是使用 CLI 工具。

使用 ActiveMQ Admin Console 创建消息队列比较直观。首先,确保 ActiveMQ 服务器已经启动,然后在浏览器中访问http://localhost:8161/admin(这里假设 ActiveMQ 运行在本地,端口为 8161),输入之前配置的用户名和密码(默认是 admin/admin)登录到管理控制台。在控制台页面中,找到 “Queues” 或 “Topics” 选项卡(取决于你要创建的是队列还是主题),点击 “Create a new queue” 或 “Create a new topic”,在弹出的表单中输入队列或主题的名称,比如 “my - queue”,然后点击 “Create” 按钮,这样就成功创建了一个消息队列或主题。

如果想使用 CLI 工具创建消息队列,可以先打开命令行终端,进入到 ActiveMQ 的安装目录下的bin目录。然后执行相应的命令,例如创建队列可以使用以下命令(假设 ActiveMQ 安装在/usr/local/activemq):

 

cd /usr/local/activemq/bin

./activemq queue create my-queue

执行完命令后,系统会提示队列创建成功的信息,这样我们就通过 CLI 工具创建好了一个消息队列。

(五)编写消息生产者

接下来,我们展示如何创建生产者类,使用JMSTemplate或JmsMessagingTemplate发送消息。首先创建一个生产者类,比如ProducerService,代码如下:

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.jms.core.JmsMessagingTemplate;

import org.springframework.stereotype.Service;

@Service

public class ProducerService {

@Autowired

private JmsMessagingTemplate jmsMessagingTemplate;

public void sendMessage(String destination, String message) {

jmsMessagingTemplate.convertAndSend(destination, message);

}

}

在这个类中,我们通过@Autowired注解注入了JmsMessagingTemplate,它是 Spring 提供的用于发送和接收消息的模板类。sendMessage方法接收两个参数,destination表示消息发送的目的地,也就是我们之前创建的队列或主题的名称,message则是要发送的消息内容。在方法内部,调用jmsMessagingTemplate.convertAndSend(destination, message)方法将消息发送到指定的目的地。

如果想使用JMSTemplate发送消息,代码如下:

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.jms.core.JmsTemplate;

import org.springframework.stereotype.Service;

@Service

public class ProducerService {

@Autowired

private JmsTemplate jmsTemplate;

public void sendMessage(String destination, String message) {

jmsTemplate.convertAndSend(destination, message);

}

}

可以看到,使用JMSTemplate和JmsMessagingTemplate发送消息的方式非常相似,JmsMessagingTemplate实际上是对JMSTemplate的进一步封装,提供了更简洁的 API。

(六)编写消息消费者

创建消费者类,使用@JmsListener注解监听消息队列并处理消息。创建一个消费者类,比如ConsumerService,代码如下:

 

import org.springframework.jms.annotation.JmsListener;

import org.springframework.stereotype.Service;

@Service

public class ConsumerService {

@JmsListener(destination = "my-queue")

public void receiveMessage(String message) {

System.out.println("Received message: " + message);

// 这里可以添加对消息的具体处理逻辑

}

}

在这个类中,我们使用@JmsListener注解来监听指定的队列。@JmsListener注解的destination属性指定了要监听的队列名称,这里是 “my - queue”,也就是我们之前创建的队列。当有消息发送到这个队列时,receiveMessage方法就会被调用,参数message就是接收到的消息内容。在方法内部,我们先简单地将接收到的消息打印出来,实际应用中可以根据业务需求添加更复杂的处理逻辑,比如解析消息内容、更新数据库等。

http://www.xdnf.cn/news/211735.html

相关文章:

  • 跨平台项目部署全攻略:Windows后端+Mac前端在服务器的协同实战
  • Arduion 第一天,变量的详细解析
  • 三格电子——四路CAN转4G网关使用中的常见问题
  • 【深度学习新浪潮】ISP芯片算法技术简介及关键技术分析
  • 深度解析 MyBatis`@TableField(typeHandler = JacksonTypeHandler.class)`:优雅处理复杂数据存储
  • 深入理解二分查找
  • AI防摔倒检测系统
  • 实验七:基于89C51和DS18B20的温度采集与显示
  • 【从滚动条缺失到布局体系:前端布局问题的系统性思考】
  • pytorch 一些常用语法
  • 图漾官网Sample_V1版本C++语言完整参考例子---单相机版本
  • 企业办公协同平台安全一体化生态入住技术架构与接口标准分析报告
  • ubnuntu使用conda进行虚拟环境迁移,复制,克隆
  • Dify 使用模版转换实现更丰富的输入格式支持
  • linux FTP服务器搭建
  • 通信协议——SPI通信协议
  • Go语言中的错误处理
  • CSS:编写位置分类
  • PDF编辑器:Foxit PDF Editor Pro 版功能解析
  • JVM对象存储格式
  • 解决调用Claude 3.7接口 403 Request not allowed问题
  • 贝叶斯优化RF预测模型
  • 轻松实现CI/CD: 用Go编写的命令行工具简化Jenkins构建
  • 处理pdf文件的常用库unstructured和PyPDF2
  • 【PyTorch动态计算图原理精讲】从入门到灵活应用
  • vscode 配置qt
  • WEB漏洞--CSRF及SSRF案例
  • 可靠性工程:加速因子与筛选度计算模型解析
  • 修改输入框选择框颜色
  • jspm老年体检信息管理系统(源码+lw+部署文档+讲解),源码可白嫖!