【Spring云原生系列】SpringBoot+Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合

🎉🎉欢迎光临,终于等到你啦🎉🎉

🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀

🌟持续更新的专栏 《Spring 狂野之旅:从入门到入魔》 🚀

本专栏带你从Spring入门到入魔

这是苏泽的个人主页可以看到我其他的内容哦👇👇

努力的苏泽http://suzee.blog.csdn.net/


Spring Cloud Stream构建在SpringBoot之上,提供了Kafka,RabbitMQ等消息中间件的个性化配置,引入了发布订阅、消费组和分区的语义概念 没学过消息中间件的可以看我之前的文章KafkaRabbitMQ

下面是正片 按照自己的口味来食用哦(有比较难懂的地方)

目录

[本文是通过大量阅读 和最近的一些项目的思考和总结 写出来的 关于Spring Cloud Stream的文章不少 但我更想以观众能够轻松理解并且运用到自己的项目当中 我认为这才是技术存在的意义](#本文是通过大量阅读 和最近的一些项目的思考和总结 写出来的 关于Spring Cloud Stream的文章不少 但我更想以观众能够轻松理解并且运用到自己的项目当中 我认为这才是技术存在的意义)

[Spring Cloud Stream: 消息驱动架构](#Spring Cloud Stream: 消息驱动架构)

引言

[Spring Cloud Stream的概念和目标](#Spring Cloud Stream的概念和目标)

事件驱动架构在现代微服务应用程序中的重要性

[先来认识Spring Cloud Stream架构](#先来认识Spring Cloud Stream架构)

消息驱动架构(MDA)

两者之间的关系

[Spring Cloud Stream作为实现MDA的框架 他是怎么做的呢? 我把他分成以下几点:](#Spring Cloud Stream作为实现MDA的框架 他是怎么做的呢? 我把他分成以下几点:)

[那么我们了解了其思想和架构 我们要如何建立到我们自己的项目当中应用这种方式呢? 这是一个很关键的问题](#那么我们了解了其思想和架构 我们要如何建立到我们自己的项目当中应用这种方式呢? 这是一个很关键的问题)

实例讲解

[步骤 1: 定义平台无关模型(PIM)](#步骤 1: 定义平台无关模型(PIM))

[步骤 2: 配置消息中间件绑定器](#步骤 2: 配置消息中间件绑定器)

[步骤 3: 实现消息转换和处理](#步骤 3: 实现消息转换和处理)

[步骤 4: 实现消息发送和接收的代码](#步骤 4: 实现消息发送和接收的代码)

[步骤 5: 实现业务逻辑](#步骤 5: 实现业务逻辑)

[以上就是一个很简单的MDA框架的业务demo的实现啦 再结合中间件的知识学习加以实践 就能较好的构建一个云原生的项目啦](#以上就是一个很简单的MDA框架的业务demo的实现啦 再结合中间件的知识学习加以实践 就能较好的构建一个云原生的项目啦)

[希望能够帮到有需要的读者 如有纰漏 望指出!](#希望能够帮到有需要的读者 如有纰漏 望指出!)

[关注我 深入学习Spring云原生系列!一起努力~](#关注我 深入学习Spring云原生系列!一起努力~)


Spring Cloud Stream: 消息驱动架构

引言

随着云计算、微服务和大数据技术的快速发展,构建可扩展、高性能和弹性的应用程序变得越来越重要。为了满足这些要求,许多开发人员转向了事件驱动架构,它允许应用程序通过基于事件的方式相互通信,从而提高了系统的响应速度和伸缩性。在这个背景下,Spring Cloud Stream应运而生,它是一个用于构建基于事件驱动的微服务应用程序的框架,可以与现有的消息中间件(如Apache Kafka和RabbitMQ)无缝集成。

Spring Cloud Stream的概念和目标

Spring Cloud Stream是一个用于构建基于事件驱动的微服务应用程序的框架,其核心目标是简化开发过程,降低消息通信的复杂性,从而使开发人员能够专注于编写业务逻辑。Spring Cloud Stream通过提供Binder抽象,将应用程序与消息中间件解耦,让开发人员无需关心底层通信细节。同时,它还提供了一套丰富的API和特性,如消息分组、分区和错误处理,使得构建强大、可扩展的事件驱动应用程序变得更加简单。

事件驱动架构在现代微服务应用程序中的重要性

事件驱动架构是指应用程序组件之间通过事件进行通信的架构。在这种架构中,组件之间的通信是异步的,基于发布-订阅模式,这有助于实现以下几个关键优势:

  1. 可伸缩性:应用程序可以通过增加或减少组件实例来应对不断变化的负载,而不会对整个系统产生负面影响。
  2. 解耦:组件之间的通信是基于事件的,它们无需知道对方的内部实现,这有助于降低系统的复杂性和维护成本。
  3. 高性能:事件驱动架构允许应用程序以并行方式处理事件,从而提高了系统的响应速度和吞吐量。
  4. 弹性:由于组件之间的通信是异步的,当某个组件出现故障时,其他组件可以继续处理事件,降低了单点故障的风险。

先来认识Spring Cloud Stream架构

消息驱动架构(MDA)

想象一下,我们要建造一座房子。传统的方式是,我们需要手工完成从设计到建造的每一个步骤。我们首先创建设计图纸,然后按照图纸上的规格和要求一步步地建造房子。

而在MDA的方式下,我们使用了一种自动化的工具来简化这个过程。我们首先创建一个高度抽象的模型,就像是一个概念上的房子草图。这个模型与具体的实现技术无关,只关注房子的整体结构和功能。

接下来,我们使用工具将这个高级模型转换为与特定实现技术相关的模型,就像是根据草图创建了一份针对具体施工工艺的图纸。例如,我们可以将高级模型转换为使用钢筋混凝土结构的房子模型。

最后,我们使用工具将这个特定实现技术的模型转换为实际的代码,就像是根据图纸建造房子的过程。这些代码与应用技术密切相关,最终实现了我们所设计的系统。

这种方式的好处是,自动化工具帮助我们完成了从高级模型到具体代码的转换,省去了手工操作的繁琐过程。这样,开发人员可以更加清晰地理解整个系统的架构,而不会受到具体实现技术的干扰。同时,对于复杂的系统,也减少了开发人员的工作量。

两者之间的关系

Spring Cloud Stream作为实现MDA的框架 他是怎么做的呢? 我把他分成以下几点:

  1. 定义平台无关模型(PIM):

    在Spring Cloud Stream中,你可以定义一个高度抽象的PIM,它描述了消息的生产者和消费者之间的通信和交互方式,而与具体的消息中间件实现无关。PIM可以包括消息的格式、结构、交换模式等。这个PIM可以作为系统设计的核心模型,独立于具体的实现技术。

  2. 选择和配置绑定器(Binder):

    Spring Cloud Stream提供了与多种消息中间件集成的绑定器,如Kafka、RabbitMQ等。绑定器可以将PIM与特定的消息中间件进行连接,使得消息的发送和接收可以与具体的消息中间件实现进行交互。通过选择和配置适当的绑定器,你可以将PIM转换为特定的平台相关模型(PSM),以便与消息中间件进行通信。

  3. 实现消息转换和处理:

    Spring Cloud Stream提供了消息转换的机制,允许你定义如何将原始消息转换为特定的领域对象,并在消费者之间传递。你可以使用消息转换器来处理消息的序列化和反序列化,以及将消息转换为应用程序所需的数据结构。这样,你可以在系统中实现解耦合和灵活的消息处理。

  4. 自动化生成代码:

    Spring Cloud Stream提供了自动化的代码生成能力,将PSM转换为具体的代码实现。你只需要定义好PIM和PSM之间的映射关系,Spring Cloud Stream会根据这些映射关系自动生成生产者和消费者的代码,从而实现消息的发送和接收。这样,你可以专注于定义PIM和PSM,并通过自动生成的代码实现实际的消息处理逻辑。

那么我们了解了其思想和架构 我们要如何建立到我们自己的项目当中应用这种方式呢? 这是一个很关键的问题

实例讲解

拿之前做过的一个商城系统来说,其中包含订单服务和库存服务之间的消息通信。订单服务负责接收订单创建请求并发送订单信息给库存服务,库存服务接收订单信息并更新库存。

步骤 1: 定义平台无关模型(PIM)

在订单服务和库存服务之间定义一个平台无关模型,例如一个名为Order的Java类,表示订单信息。

java 复制代码
public class Order {
    private String orderId;
    private String productId;
    private int quantity;
    // 其他订单相关的属性和方法
    
    // Getters and setters
}

步骤 2: 配置消息中间件绑定器

在订单服务和库存服务的配置文件中,配置Spring Cloud Stream使用合适的消息中间件绑定器。在这个例子中,我们使用RabbitMQ作为消息中间件。

订单服务的配置文件(application.properties):

java 复制代码
spring.cloud.stream.bindings.sendOrder-out-destination=order-exchange

库存服务的配置文件(application.properties):

java 复制代码
spring.cloud.stream.bindings.receiveOrder-in-destination=order-exchange

步骤 3: 实现消息转换和处理

在订单服务中,定义一个消息发送接口并实现消息转换和发送逻辑。

java 复制代码
@EnableBinding(OrderSource.class)
public class OrderService {
    
    @Autowired
    private OrderSource orderSource;
    
    public void createOrder(Order order) {
        // 执行订单创建逻辑
        
        // 发送订单消息
        orderSource.sendOrder().send(MessageBuilder.withPayload(order).build());
    }
}

interface OrderSource {
    @Output("sendOrder")
    MessageChannel sendOrder();
}

在库存服务中,定义一个消息接收接口并实现消息处理逻辑。

java 复制代码
@EnableBinding(OrderSink.class)
public class InventoryService {
    
    @StreamListener(target = "receiveOrder")
    public void handleOrder(Order order) {
        // 执行库存更新逻辑
    }
}

interface OrderSink {
    @Input("receiveOrder")
    SubscribableChannel receiveOrder();
}

步骤 4: 实现消息发送和接收的代码

在订单服务中,定义一个消息发送接口并实现消息发送逻辑。

java 复制代码
@EnableBinding(OrderSource.class)
public class OrderService {
    
    @Autowired
    private OrderSource orderSource;
    
    public void createOrder(Order order) {
        // 执行订单创建逻辑
        
        // 发送订单消息
        orderSource.sendOrder().send(MessageBuilder.withPayload(order).build());
    }
}

interface OrderSource {
    @Output("sendOrder")
    MessageChannel sendOrder();
}

在库存服务中,定义一个消息接收接口并实现消息处理逻辑。

java 复制代码
@EnableBinding(OrderSink.class)
public class InventoryService {
    
    @StreamListener(target = "receiveOrder")
    public void handleOrder(Order order) {
        // 执行库存更新逻辑
    }
}

interface OrderSink {
    @Input("receiveOrder")
    SubscribableChannel receiveOrder();
}

步骤 5: 实现业务逻辑

根据具体的业务需求,在订单服务和库存服务中编写业务逻辑来处理接收到的消息。例如,在库存服务中,你可以根据接收到的订单消息更新库存信息。

java 复制代码
@EnableBinding(OrderSink.class)
public class InventoryService {
    
    @Autowired
    private InventoryRepository inventoryRepository;
    
    @StreamListener(target = "receiveOrder")
    public void handleOrder(Order order) {
        // 根据订单消息更新库存信息
        String productId = order.getProductId();
        int quantity = order.getQuantity();
        
        // 执行库存更新逻辑
        inventoryRepository.updateInventory(productId, quantity);
    }
}

以上就是一个很简单的MDA框架的业务demo的实现啦 再结合中间件的知识学习加以实践 就能较好的构建一个云原生的项目啦


希望能够帮到有需要的读者 如有纰漏 望指出!

关注我 深入学习Spring云原生系列!一起努力~

相关推荐
leason00143 分钟前
Pod的优雅上下线
云原生·运维开发
荆州克莱1 小时前
腾讯二面:MySQL的半同步是什么?不是MySQL的两阶段提交,那是什么?
spring boot·spring·spring cloud·css3·技术
黑客呀1 小时前
云原生安全风险分析
安全·云原生
阿里云云原生2 小时前
杭州铭师堂的云原生升级实践
阿里云·云原生
xiangzhihong811 小时前
使用 Docker 构建 preboot 交叉编译环境
云原生·eureka
今天还没学习12 小时前
LabVIEW之树形控件
架构·labview·高级控件
7yewh13 小时前
自制红外热像仪(二) MLX90640移植 RP2040 STM32 ESP32
驱动开发·stm32·单片机·嵌入式硬件·mcu·计算机视觉
运维&陈同学14 小时前
【Logstash02】企业级日志分析系统ELK之Logstash 输入 Input 插件
linux·运维·elk·elasticsearch·云原生·自动化·logstash
Akamai中国14 小时前
大语言模型兵马未动,数据准备粮草先行
人工智能·语言模型·自然语言处理·云原生·架构·云计算·云平台
csdn56597385016 小时前
EMR Serverless Spark | 全托管一站式大规模数据处理和分析Serverless平台
云原生·spark·serverless·emr serverless