简介: 本文将 rocktmq-spring-boot 的设计实现做一个简单的介绍,读者可以通过本文了解将 RocketMQ Client 端集成为 spring-boot-starter 框架的开发细节,然后通过一个简单的示例来一步一步的讲解如何使用这个 spring-boot-starter 工具包来配置,发送和消费 RocketMQ 消息。

作者 | 辽天
来源 | 阿里巴巴云原生公众号

导读:本文将 rocktmq-spring-boot 的设计实现做一个简单的介绍,读者可以通过本文了解将 RocketMQ Client 端集成为 spring-boot-starter 框架的开发细节,然后通过一个简单的示例来一步一步的讲解如何使用这个 spring-boot-starter 工具包来配置,发送和消费 RocketMQ 消息。

在 Spring 生态中玩转 RocketMQ 系列文章:

本文配套可交互教程已登录阿里云知行动手实验室,PC 端登录start.aliyun.com 在浏览器中立即体验。

通过本文,您将了解到:

  • Spring 的消息框架介绍
  • rocketmq-spring-boot 具体实现
  • 使用示例

前言

上世纪 90 年代末,随着 Java EE(Enterprise Edition) 的出现,特别是 Enterprise Java Beans 的使用需要复杂的描述符配置和死板复杂的代码实现,增加了广大开发者的学习曲线和开发成本,由此基于简单的 XML 配置和普通 Java 对象(Plain Old Java Objects)的 Spring 技术应运而生,依赖注入(Dependency Injection), 控制反转(Inversion of Control)和面向切面编程(AOP)的技术更加敏捷地解决了传统 Java 企业及版本的不足。

随着 Spring 的持续演进,基于注解(Annotation)的配置逐渐取代了 XML 文件配置,2014 年 4 月 1 日,Spring Boot 1.0.0 正式发布,它基于“约定大于配置”(Convention over configuration)这一理念来快速地开发、测试、运行和部署 Spring 应用,并能通过简单地与各种启动器(如 spring-boot-web-starter)结合,让应用直接以命令行的方式运行,不需再部署到独立容器中。这种简便直接快速构建和开发应用的过程,可以使用约定的配置并且简化部署,受到越来越多的开发者的欢迎。

Apache RocketMQ 是业界知名的分布式消息和流处理中间件,简单地理解,它由 Broker 服务器和客户端两部分组成:

其中客户端一个是消息发布者客户端(Producer),它负责向 Broker 服务器发送消息;另外一个是消息的消费者客户端(Consumer),多个消费者可以组成一个消费组,来订阅和拉取消费 Broker 服务器上存储的消息。

为了利用 Spring Boot 的快速开发和让用户能够更灵活地使用 RocketMQ 消息客户端,Apache RocketMQ 社区推出了 spring-boot-starter 实现。随着分布式事务消息功能在 RocketMQ 4.3.0 版本的发布,近期升级了相关的 spring-boot 代码,通过注解方式支持分布式事务的回查和事务消息的发送。

本文将对当前的设计实现做一个简单的介绍,读者可以通过本文了解将 RocketMQ Client 端集成为 spring-boot-starter 框架的开发细节,然后通过一个简单的示例来一步一步的讲解如何使用这个 spring-boot-starter 工具包来配置,发送和消费 RocketMQ 消息。

Spring 中的消息框架

顺便在这里讨论一下在 Spring 中关于消息的两个主要的框架,即 Spring Messaging 和 Spring Cloud Stream。它们都能够与 Spring Boot 整合并提供了一些参考的实现。和所有的实现框架一样,消息框架的目的是实现轻量级的消息驱动的微服务,可以有效地简化开发人员对消息中间件的使用复杂度,让系统开发人员可以有更多的精力关注于核心业务逻辑的处理。

1. Spring Messaging

Spring Messaging 是 Spring Framework 4 中添加的模块,是 Spring 与消息系统集成的一个扩展性的支持。它实现了从基于 JmsTemplate 的简单的使用 JMS 接口到异步接收消息的一整套完整的基础架构,Spring AMQP 提供了该协议所要求的类似的功能集。在与 Spring Boot 的集成后,它拥有了自动配置能力,能够在测试和运行时与相应的消息传递系统进行集成。

单纯对于客户端而言,Spring Messaging 提供了一套抽象的 API 或者说是约定的标准,对消息发送端和消息接收端的模式进行规定,不同的消息中间件提供商可以在这个模式下提供自己的 Spring 实现:在消息发送端需要实现的是一个 XXXTemplate 形式的 Java Bean,结合 Spring Boot 的自动化配置选项提供多个不同的发送消息方法;在消息的消费端是一个 XXXMessageListener 接口(实现方式通常会使用一个注解来声明一个消息驱动的 POJO),提供回调方法来监听和消费消息,这个接口同样可以使用 Spring Boot 的自动化选项和一些定制化的属性。

如果有兴趣深入的了解 Spring Messaging 及针对不同的消息产品的使用,推荐阅读这个文件。参考 Spring Messaging 的既有实现,RocketMQ 的 spring-boot-starter 中遵循了相关的设计模式并结合 RocketMQ 自身的功能特点提供了相应的 API(如顺序、异步和事务半消息等)。

2. Spring Cloud Stream

Spring Cloud Stream 结合了 Spring Integration 的注解和功能,它的应用模型如下:


该图片引自 spring cloud stream

Spring Cloud Stream 框架中提供一个独立的应用内核,它通过输入(@Input)和输出(@Output)通道与外部世界进行通信,消息源端(Source)通过输入通道发送消息,消费目标端(Sink)通过监听输出通道来获取消费的消息。这些通道通过专用的 Binder 实现与外部代理连接。开发人员的代码只需要针对应用内核提供的固定的接口和注解方式进行编程,而不需要关心运行时具体的 Binder 绑定的消息中间件。在运行时,Spring Cloud Stream 能够自动探测并使用在 classpath 下找到的Binder。

这样开发人员可以轻松地在相同的代码中使用不同类型的中间件:仅仅需要在构建时包含进不同的 Binder。在更加复杂的使用场景中,也可以在应用中打包多个 Binder 并让它自己选择 Binder,甚至在运行时为不同的通道使用不同的 Binder。

Binder 抽象使得 Spring Cloud Stream 应用可以灵活的连接到中间件,加之 Spring Cloud Stream 使用利用了 Spring Boot 的灵活配置配置能力,这样的配置可以通过外部配置的属性和 Spring Boot 支持的任何形式来提供(包括应用启动参数、环境变量和 application.yml 或者 application.properties 文件),部署人员可以在运行时动态选择通道连接 destination(例如,Kafka 的 topic 或者 RabbitMQ 的 exchange)。

Binder SPI 的方式来让消息中间件产品使用可扩展的 API 来编写相应的 Binder,并集成到 Spring Cloud Steam 环境,目前 RocketMQ 还没有提供相关的 Binder,我们计划在下一步将完善这一功能,也希望社区里有这方面经验的同学积极尝试,贡献 PR 或建议。

spring-boot-starter的实现

在开始的时候我们已经知道,spring boot starter 构造的启动器对于使用者是非常方便的,使用者只要在 pom.xml引入starter 的依赖定义,相应的编译,运行和部署功能就全部自动引入。因此常用的开源组件都会为 Spring 的用户提供一个 spring-boot-starter 封装给开发者,让开发者非常方便集成和使用,这里我们详细的介绍一下 RocketMQ(客户端)的 starter 实现过程。

1. spring-boot-starter 的实现步骤

对于一个 spring-boot-starter 实现需要包含如下几个部分:

1)在 pom.xml 的定义

  • 定义最终要生成的 starter 组件信息
<groupId>org.apache.rocketmq</groupId>
<artifactId>spring-boot-starter-rocketmq</artifactId>
<version>1.0.0-SNAPSHOT</version>
  • 定义依赖包

它分为两个部分:Spring 自身的依赖包和 RocketMQ 的依赖包。

2)配置文件类

定义应用属性配置文件类 RocketMQProperties,这个 Bean 定义一组默认的属性值。用户在使用最终的 starter 时,可以根据这个类定义的属性来修改取值,当然不是直接修改这个类的配置,而是 spring-boot 应用中对应的配置文件:src/main/resources/application.properties。

3)定义自动加载类

定义 src/resources/META-INF/spring.factories 文件中的自动加载类, 其目的是让 spring boot 更具文中中所指定的自动化配置类来自动初始化相关的 Bean、Component 或 Service,它的内容如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.apache.rocketmq.spring.starter.RocketMQAutoConfiguration

在 RocketMQAutoConfiguration 类的具体实现中,定义开放给用户直接使用的 Bean 对象包括:

  • RocketMQProperties 加载应用属性配置文件的处理类;
  • RocketMQTemplate 发送端用户发送消息的发送模板类;
  • ListenerContainerConfiguration 容器 Bean 负责发现和注册消费端消费实现接口类,这个类要求:由 @RocketMQMessageListener 注解标注;实现 RocketMQListener 泛化接口。

4)最后具体地进行 RpcketMQ 相关的封装

在发送端(producer)和消费端(consumer)客户端分别进行封装,在当前的实现版本提供了对 Spring Messaging 接口的兼容方式。

2. 消息发送端实现

1)普通发送端

发送端的代码封装在 RocketMQTemplate POJO 中,下图是发送端的相关代码的调用关系图:

为了与 Spring Messaging 的发送模板兼容,在 RocketMQTemplate 集成了 AbstractMessageSendingTemplate 抽象类,来支持相关的消息转换和发送方法,这些方法最终会代理给 doSend() 方法、doSend() 以及 RocoketMQ 所特有的一些方法如异步,单向和顺序等方法直接添加到 RoketMQTempalte 中,这些方法直接代理调用到 RocketMQ 的 Producer API 来进行消息的发送。

2)事务消息发送端

对于事务消息的处理,在消息发送端进行了部分的扩展,参考上面的调用关系类图。

RocketMQTemplate 里加入了一个发送事务消息的方法 sendMessageInTransaction(),并且最终这个方法会代理到 RocketMQ 的 TransactionProducer 进行调用,在这个 Producer 上会注册其关联的 TransactionListener 实现类,以便在发送消息后能够对 TransactionListener 里的方法实现进行调用。

3. 消息消费端实现

在消费端 Spring-Boot 应用启动后,会扫描所有包含 @RocketMQMessageListener 注解的类(这些类需要集成 RocketMQListener 接口,并实现 onMessage()方法),这个 Listener 会一对一的被放置到。

DefaultRocketMQListenerContainer 容器对象中,容器对象会根据消费的方式(并发或顺序),将 RocketMQListener 封装到具体的 RocketMQ 内部的并发或者顺序接口实现。在容器中创建 RocketMQ Consumer 对象,启动并监听定制的 Topic 消息,如果有消费消息,则回调到 Listener 的 onMessage() 方法。

使用示例

上面的一章介绍了 RocketMQ 在 spring-boot-starter 方式的实现,这里通过一个最简单的消息发送和消费的例子来介绍如何使这个 rocketmq-spring-boot-starter。

1. RocketMQ 服务端的准备

1)启动 NameServer 和 Broker

要验证 RocketMQ 的 Spring-Boot 客户端,首先要确保 RocketMQ 服务正确的下载并启动。可以参考 RocketMQ 主站的快速开始来进行操作。确保启动 NameServer 和 Broker 已经正确启动。

2)创建实例中所需要的 Topics

在执行启动命令的目录下执行下面的命令行操作:

bash bin/mqadmin updateTopic -c DefaultCluster -t string-topic

2. 编译 rocketmq-spring-boot-starter

目前的 spring-boot-starter 依赖还没有提交的 Maven 的中心库,用户使用前需要自行下载 git 源码,然后执行 mvn clean install 安装到本地仓库。

git clone https://github.com/apache/rocketmq-externals.git
cd rocketmq-spring-boot-starter
mvn clean install

3. 编写客户端代码

用户如果使用它,需要在消息的发布和消费客户端的 maven 配置文件 pom.xml 中添加如下的依赖:

属性 spring-boot-starter-rocketmq-version 的取值为:1.0.0-SNAPSHOT, 这与上一步骤中执行安装到本地仓库的版本一致。

1)消息发送端的代码

发送端的配置文件 application.properties:

发送端的 Java 代码:

2)消息消费端代码

消费端的配置文件 application.properties:

消费端的 Java 代码:

这里只是简单的介绍了使用 spring-boot 来编写最基本的消息发送和接收的代码,如果需要了解更多的调用方式,如: 异步发送,对象消息体,指定 tag 标签以及指定事务消息,请参看 github 的说明文档和详细的代码。我们后续还会对这些高级功能进行陆续的介绍。

作者简介

辽天,阿里巴巴技术专家,Apache RocketMQ 内核控,拥有多年分布式系统研发经验,对 Microservice、Messaging 和 Storage 等领域有深刻理解, 目前专注 RocketMQ 内核优化以及 Messaging 生态建设。

原文链接

本文为阿里云原创内容,未经允许不得转载。

使用 rocketmq-spring-boot-starter 来配置、发送和消费 RocketMQ 消息的更多相关文章

  1. Druid Spring Boot Starter 从配置到简单运行 -解决zone不匹配 -解决dataSource加载失败

    Druid Spring Boot Starter 中文 | English Druid Spring Boot Starter 用于帮助你在Spring Boot项目中轻松集成Druid数据库连接池 ...

  2. 自定义的Spring Boot starter如何设置自动配置注解

    本文首发于个人网站: 在Spring Boot实战之定制自己的starter一文最后提到,触发Spring Boot的配置过程有两种方法: spring.factories:由Spring Boot触 ...

  3. Spring Boot Starter 介绍

    http://www.baeldung.com/spring-boot-starters 作者:baeldung 译者:http://oopsguy.com 1.概述 依赖管理是任何复杂项目的关键部分 ...

  4. 一个简单易上手的短信服务Spring Boot Starter

    前言 短信服务在用户注册.登录.找回密码等相关操作中,可以让用户使用更加便捷,越来越多的公司都采用短信验证的方式让用户进行操作,从而提高用户的实用性. Spring Boot Starter 由于 S ...

  5. 最详细的自定义Spring Boot Starter开发教程

    1. 前言 随着Spring的日渐臃肿,为了简化配置.开箱即用.快速集成,Spring Boot 横空出世. 目前已经成为 Java 目前最火热的框架了.平常我们用Spring Boot开发web应用 ...

  6. spring -boot s-tarter 详解

    Starter POMs是可以包含到应用中的一个方便的依赖关系描述符集合.你可以获取所有Spring及相关技术的一站式服务,而不需要翻阅示例代码,拷贝粘贴大量的依赖描述符.例如,如果你想使用Sprin ...

  7. 初识Spring Boot框架(二)之DIY一个Spring Boot的自动配置

    在上篇博客初识Spring Boot框架中我们初步见识了SpringBoot的方便之处,很多小伙伴可能也会好奇这个Spring Boot是怎么实现自动配置的,那么今天我就带小伙伴我们自己来实现一个简单 ...

  8. Spring Boot 2.0 配置图文教程

    摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 本章内容 自定义属性快速入门 外化配置 自动配置 自定义创建 ...

  9. spring boot多数据源配置(mysql,redis,mongodb)实战

    使用Spring Boot Starter提升效率 虽然不同的starter实现起来各有差异,但是他们基本上都会使用到两个相同的内容:ConfigurationProperties和AutoConfi ...

  10. Spring Boot (一): Spring Boot starter自定义

    前些日子在公司接触了spring boot和spring cloud,有感于其大大简化了spring的配置过程,十分方便使用者快速构建项目,而且拥有丰富的starter供开发者使用.但是由于其自动化配 ...

随机推荐

  1. 从API到Agent:万字长文洞悉LangChain工程化设计

    我想做一个尝试,看看能不能用尽量清晰的逻辑,给"AI外行人士"(当然,我也是--)引入一下LangChain,试着从工程角度去理解LangChain的设计和使用.同时大家也可以将此 ...

  2. 简单使用vim编辑器的用法

    vim的使用笔记可以涵盖很多内容,以下是一些基本操作和常见命令的简要总结: 启动Vim 打开或创建文件:vim filename 基本模式切换 正常模式(Normal Mode):启动时默认进入此模式 ...

  3. Spring Boot学习日记15

    使用thymeleaf <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.o ...

  4. 不要升级!不要升级!MacOS 14.4 引发Java 应用崩溃

    如果最近您收到了MacOS 14.4的升级提醒,那么建议你暂时先不要升级! 在x上,Java开发领域的一些大v们,也发现了这个问题,并提醒大家不要升级. 根据Java官方发布的文章了解到,该问题主要是 ...

  5. 深入分析Java中的PriorityQueue底层实现与源码

    本文分享自华为云社区<滚雪球学Java(70):深入理解Java中的PriorityQueue底层实现与源码分析>,作者: bug菌. 环境说明:Windows 10 + IntelliJ ...

  6. 三维模型3DTile格式轻量化压缩处理的数据质量提升方法分析

    三维模型3DTile格式轻量化压缩处理的数据质量提升方法分析 在处理三维模型3DTile格式的轻量化压缩时,如何在减少数据量的同时,保证或提升数据质量是一大挑战.以下为一些提升数据质量的方法分析: 改 ...

  7. 记录--开局一张图,构建神奇的 CSS 效果

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 假设,我们有这样一张 Gif 图: 利用 CSS,我们尝试来搞一些事情. 图片的 Glitch Art 风 在这篇文章中 --CSS 故障 ...

  8. proteus的五状态显示控制器

    proteus的五状态显示控制器 1.实验原理 使用的核心器件还是4028,BCD译码器.将输入的四个信号接入输入端,输出信号选取0.1.2.4.8这五个输出状态驱动led显示.发光LED需要加入保护 ...

  9. KingbaseES V8R6 集群运维案例 -- 禁止普通用户su到root

    案例说明: 在集群管理中,会使用到root权限(如ip.aring命令等),为安全需要,有的生产环境禁止普通用户su切换到root,本案例测试了禁止普通用户su切换到root对集群管理带来的影响. 集 ...

  10. Boruvka 简介

    Boruvka 是一种最小生成树算法,用于求解稠密图的 MST. [典题]CF Xor-MST: 发现边数是 $n^2$ 级别的,直接把 Kruskal 和 Prim ban 了,所以考虑使用 Bor ...