Reader small image

You're reading from  Mastering Spring Cloud

Product typeBook
Published inApr 2018
Reading LevelIntermediate
PublisherPackt
ISBN-139781788475433
Edition1st Edition
Languages
Right arrow
Author (1)
Piotr Mińkowski
Piotr Mińkowski
author image
Piotr Mińkowski

Piotr works as a Solution Architect at Red Hat. He has several years of experience in software architecture and development. During this time, he was working in large organizations, where he was responsible for IT transformation to the modern cloud-native development approach. He is interested in technologies related to programming, containerization, and microservices. He writes about it in his blog https://piotrminkowski.com.
Read more about Piotr Mińkowski

Right arrow

Chapter 11. Message-Driven Microservices

We have already discussed many features around microservice-based architecture provided by Spring Cloud. However, we have always been considering synchronous, RESTful-based inter-service communication. As you probably remember from Chapter 1, Introduction to Microservices, there are some other popular communication styles, such as publish/subscribe or asynchronous, event-driven point-to-point messaging. In this chapter, I would like to introduce a different approach to microservices than that presented in previous chapters. We will talk in more detail about how you can work with Spring Cloud Stream in order to build message-driven microservices.

Topics we will cover in this chapter include:

  • The main terms and concepts related to Spring Cloud Stream
  • Using RabbitMQ and Apache Kafka message brokers as binders
  • The Spring Cloud Stream programming model
  • Advanced configurations of binding, producers, and consumers
  • Implementation of scaling, grouping, and partitioning...

Learning about Spring Cloud Stream


Spring Cloud Stream is built on top of Spring Boot. It allows us to create standalone, production-grade Spring applications and uses Spring Integration that helps in implementing communication with message brokers. Every application created with Spring Cloud Stream integrates with other microservices through input and output channels. Those channels are connected to external message brokers via middleware-specific binder implementations. There are two built-in binder implementations available—Kafka and Rabbit MQ.

Spring Integration extends the Spring programming model to support the well-known Enterprise Integration Patterns (EIP). EIP defines a number of components that are typically used for orchestration in distributed systems. You have probably heard about patterns such as message channels, routers, aggregators, or endpoints. A primary goal of the Spring Integration framework is to provide a simple model for building Spring applications based on EIP...

Building a messaging system


I think that the most suitable way to introduce main Spring Cloud Stream features is through the sample microservices-based system. We will lightly modify an architecture of the system that has been discussed in the previous chapters. Let me provide a short recall of that architecture. Our system is responsible for processing orders. It consists of four independent microservices. The order-service microservice first communicates with product-service in order to collect the details of the selected products, and then with customer-service to retrieve information about the customer and his accounts. Now, the orders sent to order-service will be processed asynchronously. There is still an exposed RESTful HTTP API endpoint for submitting new orders by the clients, but they are not processed by the application. It only saves new orders, sends it to a message broker, and then responds to the client that the order has been approved for processing. The main goal of the...

The publish/subscribe model


The main motivation for creating a Spring Cloud Stream project is, in fact, support for a persistent publish/subscribe model. In the previous sections, we have discussed point-to-point communication between microservices, which is just an additional feature. However, the programming model is still the same, irrespective of whether we decided to use a point-to-point or publish/subscribe model.

In publish/subscribe communication, the data is broadcast through shared topics. It reduces the complexity of both the producer and the consumer, and allows new applications to be easily added to the existing topology without any changes in flow. This can be clearly seen in the last-presented sample of the system, where we decided to add the second application that has consumed events produced by the source microservice. In comparison to the initial architecture, we had to define custom message channels dedicated for each of the target applications. With direct communication...

Configuration options


Spring Cloud Stream configuration settings may be overridden using any mechanism supported by Spring Boot, such as application arguments, environment variables, and YAML or property files. It defines a number of generic configuration options that may be applied to all binders. However, there are also some additional properties specific for a particular message broker used by the application.

Spring Cloud Stream properties

The current group of properties applies to the whole Spring Cloud Stream application. All the following properties are prefixed with  spring.cloud.stream

The advanced programming model


The basics around the Spring Cloud Stream programming model have been presented together with samples of point-to-point and publish/subscribe communication. Let's discuss some more advanced example features.

Producing messages

In all the samples presented in this chapter, we have sent orders through RESTful API for testing purposes. However, we may easily create some test data by defining the message source inside the application. Here's a bean that generates one message per second using @Poller and sends it to the output channel:

@Bean
@InboundChannelAdapter(value = Source.OUTPUT, poller = @Poller(fixedDelay = "1000", maxMessagesPerPoll = "1"))
public MessageSource<Order> ordersSource() {
    Random r = new Random();
    return () -> new GenericMessage<>(new Order(OrderStatus.NEW, (long) r.nextInt(5), Collections.singletonList((long) r.nextInt(10))));
}

Transformation

As you probably remember, account-service and product-service have been receiving...

Using Apache Kafka


I have mentioned Apache Kafka a couple of times when discussing Spring Cloud integration with message brokers. However, until now, we haven't run any samples based on that platform. The fact is that RabbitMQ tends to be the preferred choice when working with Spring Cloud projects, but Kafka is also worthy of our attention. One of its advantages over RabbitMQ is native support for partitioning, which is one of the most important features of Spring Cloud Stream.

Kafka is not a typical message broker. It is rather a distributed streaming platform. Its main feature is to allow you to publish and subscribe to streams of records. It is especially useful for real-time streaming applications that transform or react to streams of data. It is usually run as a cluster consisting of one or more servers, and stores streams of records in topics.

Running Kafka

Unfortunately, there is no official Docker image with Apache Kafka. However, we may use one that is unofficial, for example, that...

Multiple binders


In Spring Cloud Stream nomenclature, the interface that may be implemented to provide connection to physical destinations at the external middleware is called binder. Currently, there are two available built-in binder implementations—Kafka and RabbitMQ. In case you would like to provide a custom binder library, the key interface that is an abstraction for a strategy for connecting inputs and outputs to external middleware is Binder, having two methods—bindConsumer and bindProducer. For more details, you may refer to the Spring Cloud Stream specifications.

The important thing for us is an ability to use multiple binders in a single application. You can even mix different implementations, for example, RabbitMQ with Kafka. Spring Cloud Stream relies on Spring Boot's auto-configuration in the binding process. The implementation available on the classpath is used automatically. In case you would like to use both the default Binders, include the following dependencies to the project...

Summary


Spring Cloud Stream can be treated as a separate category in comparison to all the other Spring Cloud projects. It is often being associated with other projects, and which are currently strongly promoted by Pivotal Spring Cloud Data Flow. That is a toolkit for building data integration and real-time data processing pipelines. However, it is a huge subject and rather a topic of discussion for a separate book. 

More to the point, Spring Cloud Stream provides support for asynchronous messaging, which may be easily implemented using a Spring annotation style. I think that for some of you, that style of inter-service communication is not as obvious as the RESTful API model. Therefore, I have focused on showing you the examples of point-to-point and publish/subscribe communication using Spring Cloud Stream. I have also described the differences between those two styles of messaging. 

The publish/subscribe model is nothing new, but thanks to Spring Cloud Stream, it may be easily included...

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Mastering Spring Cloud
Published in: Apr 2018Publisher: PacktISBN-13: 9781788475433
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Piotr Mińkowski

Piotr works as a Solution Architect at Red Hat. He has several years of experience in software architecture and development. During this time, he was working in large organizations, where he was responsible for IT transformation to the modern cloud-native development approach. He is interested in technologies related to programming, containerization, and microservices. He writes about it in his blog https://piotrminkowski.com.
Read more about Piotr Mińkowski

Name

Default value

Description

instanceCount

1

The number of running instances of an application. For more details, refer to the Scaling and grouping section.

instanceIndex

0

The index of the instance of the application. For more details, also refer to the Scaling and grouping section.

dynamicDestinations

-

A list of destinations that can be bound dynamically.

defaultBinder

-

The default binder in case there are...