Skip to main content

[Spring Cloud Native Series] SpringBoot+Spring Cloud Stream: Message-Driven Architecture (MDA) analysis to achieve asynchronous processing and decoupling

[Spring Cloud Native Series] SpringBoot+Spring Cloud Stream: Message-Driven Architecture (MDA) analysis to achieve asynchronous processing and decoupling

[Spring Cloud Native Series] SpringBoot+Spring Cloud Stream: Message-Driven Architecture (MDA) analysis to achieve asynchronous processing and decoupling

🎉🎉Welcome, finally waiting for you🎉🎉

🏅I am Su Ze, an explorer and sharer who is passionate about technology. 🚀🚀

🌟Continuously updated column[ "Spring Wild Journey: From Getting Started to Becoming Obsessed" 🚀](https://blog.csdn.net/m0_72803988/category_12575647.html ""Spring Wild Journey: From Beginner to Obsession" 🚀")

This column will take you from getting started with Spring to being obsessed with it.

This is Su Ze’s personal homepage, you can see my other content👇👇

Hardworking Su Ze[Spring Cloud Native Series] SpringBoot+Spring Cloud Stream: Message-Driven Architecture (MDA) analysis to achieve asynchronous processing and decouplinghttp://suzee.blog.csdn.net/


Spring Cloud Stream is built on SpringBoot, provides personalized configuration of message middleware such as Kafka, RabbitMQ, and introduces the semantic concepts of publish and subscribe, consumer groups and partitions. If you have not learned message middleware, you can read my previous articles Kafka , RabbitMQ

The following is the main film. Eat it according to your own taste (there are some parts that are difficult to understand)

Table of contents

This article is written through a lot of reading and reflections and summaries on some recent projects. There are many articles about Spring Cloud Stream, but I want the audience to easily understand and apply it to their own projects. I think this is the meaning of the existence of technology.

Spring Cloud Stream: Message-driven architecture

introduction

Concepts and goals of Spring Cloud Stream

The importance of event-driven architecture in modern microservices applications

Let’s first understand the Spring Cloud Stream architecture

Message Driven Architecture (MDA)

relationship between the two

How does Spring Cloud Stream, as a framework for implementing MDA, do it? I divide it into the following points:

So now that we understand its ideas and structure, how can we apply this approach to our own projects? This is a very critical issue

Example explanation

Step 1: Define the Platform Independent Model (PIM)

Step 2: Configure the message middleware binder

Step 3: Implement message conversion and processing

Step 4: Implement the code for sending and receiving messages

Step 5: Implement business logic

The above is the implementation of a very simple business demo of the MDA framework. Combined with the knowledge learning and practice of middleware, you can better build a cloud-native project.

I hope it can help readers in need. If there are any mistakes, please point them out!

Follow me to learn more about the Spring [cloud native](/search?q=cloud native) series! Work hard together~


Spring Cloud Stream: Message-driven architecture

introduction

With the rapid development of cloud computing, microservices and big data technologies, building scalable, high-performance and elastic applications has become increasingly important. To meet these requirements, many developers turn to event-driven architecture, which allows applications to communicate with each other in an event-based manner, thereby improving system responsiveness and scalability. In this context, Spring Cloud Stream emerged as a framework for building event-driven microservice applications that can be seamlessly integrated with existing messaging middleware (such as Apache Kafka and RabbitMQ).

Concepts and goals of Spring Cloud Stream

Spring Cloud Stream is a framework for building event-driven microservice applications. Its core goal is to simplify the development process and reduce the complexity of message communication, so that developers can focus on writing business logic. Spring Cloud Stream decouples applications from message middleware by providing Binder abstraction, so that developers do not need to care about the underlying communication details. At the same time, it also provides a rich set of APIs and features, such as message grouping, partitioning, and error handling, making it easier to build powerful, scalable event-driven applications.

The importance of event-driven architecture in modern microservices applications

Event-driven architecture refers to an architecture in which application components communicate through events. In this architecture, communication between components is asynchronous and based on a publish-subscribe pattern, which helps achieve several key advantages:

  1. Scalability: Applications can respond to changing loads by adding or subtracting component instances without negatively impacting the overall system.
  2. Decoupling: Communication between components is event-based, and they do not need to know each other's internal implementation, which helps reduce system complexity and maintenance costs.
  3. High performance: The event-driven architecture allows applications to process events in a parallel manner, improving system responsiveness and throughput.
  4. Resilience: Because communication between components is asynchronous, when a component fails, other components can continue to process events, reducing the risk of single points of failure.

Let’s first understand the Spring Cloud Stream architecture

[Spring Cloud Native Series] SpringBoot+Spring Cloud Stream: Message-Driven Architecture (MDA) analysis to achieve asynchronous processing and decoupling

Message Driven Architecture (MDA)

[Spring Cloud Native Series] SpringBoot+Spring Cloud Stream: Message-Driven Architecture (MDA) analysis to achieve asynchronous processing and decoupling

Imagine we want to build a house. The traditional way is that we need to complete every step from design to construction manually. We first create design drawings and then build the house step by step according to the specifications and requirements on the drawings.

In the MDA approach, we use an automated tool to simplify this process. We start by creating a highly abstract model, like a conceptual sketch of a house. This model has nothing to do with specific implementation technology and only focuses on the overall structure and function of the house.

Next, we use tools to convert this high-level model into a model relevant to a specific implementation technology, much like creating a drawing for a specific construction process from the sketch. For example, we can convert an advanced model to a house model using reinforced concrete structures.

Finally, we use tools to convert the model of this specific implementation technology into actual code, much like the process of building a house from drawings. These codes are closely related to the application technology and ultimately realize the system we designed.

The advantage of this approach is that automated tools help us complete the conversion from high-level models to specific codes, eliminating the tedious manual process. In this way, developers can more clearly understand the architecture of the entire system without being disturbed by specific implementation technologies. At the same time, for complex systems, it also reduces the workload of developers.

[Spring Cloud Native Series] SpringBoot+Spring Cloud Stream: Message-Driven Architecture (MDA) analysis to achieve asynchronous processing and decoupling

relationship between the two

How does Spring Cloud Stream, as a framework for implementing MDA, do it? I divide it into the following points:

  1. Define a platform-independent model (PIM):
    In Spring Cloud Stream, you can define a highly abstract PIM, which describes the communication and interaction between message producers and consumers, regardless of the specific message middleware implementation. . PIM can include message format, structure, exchange mode, etc. This PIM can be used as the core model of system design, independent of specific implementation technology.

  2. Select and configure the binder (Binder):
    Spring Cloud Stream provides binders integrated with a variety of message middleware, such as Kafka, RabbitMQ, etc. The binder can connect PIM with specific message middleware, so that the sending and receiving of messages can interact with the specific message middleware implementation. By selecting and configuring the appropriate binder, you can convert a PIM into a specific platform-specific model (PSM) for communication with messaging middleware.

  3. Implement message conversion and processing:
    Spring Cloud Stream provides a message conversion mechanism, allowing you to define how to convert raw messages into specific domain objects and pass them between consumers. You can use message converters to handle the serialization and deserialization of messages, as well as converting messages into the data structures required by your application. In this way, you can achieve decoupling and flexible message processing in the system.

  4. Automated code generation:
    Spring Cloud Stream provides automated code generation capabilities to convert PSM into specific code implementations. You only need to define the mapping relationship between PIM and PSM, and Spring Cloud Stream will automatically generate producer and consumer codes based on these mapping relationships to realize the sending and receiving of messages. This way, you can focus on defining PIM and PSM and implement the actual message processing logic through automatically generated code.

So now that we understand its ideas and structure, how can we apply this approach to our own projects? This is a very critical issue

Example explanation

Take, for example, a shopping mall system that we have built before, which includes message communication between the order service and the inventory service. The order service is responsible for receiving order creation requests and sending order information to the inventory service. The inventory service receives the order information and updates the inventory.

Step 1: Define the Platform Independent Model (PIM)

Define a platform-independent model between the order service and the inventory service, such as a Java class named Order to represent order information.

     public class Order {

private String orderId;

private String productId;

private int quantity;

// Other order-related properties and methods



// Getters and setters

}



Step 2: Configure the message middleware binder

In the configuration files of the order service and inventory service, configure Spring Cloud Stream to use the appropriate message middleware binder. In this example, we use RabbitMQ as the message middleware.

Configuration file of order service (application.properties):

 
spring.cloud.stream.bindings.sendOrder-out-destination=order-exchange

Inventory service configuration file (application.properties):

 
spring.cloud.stream.bindings.receiveOrder-in-destination=order-exchange

Step 3: Implement message conversion and processing

In the order service, define a message sending interface and implement message conversion and sending logic.

     @EnableBinding(OrderSource.class)

public class OrderService {



@Autowired

private OrderSource orderSource;



public void createOrder(Order order) {

// Perform order creation logic



// Send the order message

orderSource.sendOrder().send(MessageBuilder.withPayload(order).build());

}

}



interface OrderSource {

@Output("sendOrder")

MessageChannel sendOrder();

}



In the inventory service, define a message receiving interface and implement message processing logic.

     @EnableBinding(OrderSink.class)

public class InventoryService {



@StreamListener(target = "receiveOrder")

public void handleOrder(Order order) {

// Perform inventory update logic

}

}



interface OrderSink {

@Input("receiveOrder")

SubscribableChannel receiveOrder();

}



Step 4: Implement the code for sending and receiving messages

In the order service, define a message sending interface and implement the message sending logic.

     @EnableBinding(OrderSource.class)

public class OrderService {



@Autowired

private OrderSource orderSource;



public void createOrder(Order order) {

// Perform order creation logic



// Send the order message

orderSource.sendOrder().send(MessageBuilder.withPayload(order).build());

}

}



interface OrderSource {

@Output("sendOrder")

MessageChannel sendOrder();

}



In the inventory service, define a message receiving interface and implement message processing logic.

     @EnableBinding(OrderSink.class)

public class InventoryService {



@StreamListener(target = "receiveOrder")

public void handleOrder(Order order) {

// Perform inventory update logic

}

}



interface OrderSink {

@Input("receiveOrder")

SubscribableChannel receiveOrder();

}



Step 5: Implement business logic

According to specific business needs, write business logic in the order service and inventory service to process the received messages. For example, in an inventory service, you can update inventory information based on received order messages.

     @EnableBinding(OrderSink.class)

public class InventoryService {



@Autowired

private InventoryRepository inventoryRepository;



@StreamListener(target = "receiveOrder")

public void handleOrder(Order order) {

// Update inventory information based on order messages

String productId = order.getProductId();

int quantity = order.getQuantity();



// Perform inventory update logic

inventoryRepository.updateInventory(productId, quantity);

}

}



The above is the implementation of a very simple business demo of the MDA framework. Combined with the knowledge learning and practice of middleware, you can better build a cloud-native project.


I hope it can help readers in need. If there are any mistakes, please point them out!

Follow me to learn more about the Spring cloud native series! Work hard together~