Message linkage is between application programs By exchanging "messages" such as data and processing requests A mechanism for asynchronously linking multiple applications.
In microservices design By temporarily holding the message and introducing middleware that mediates this delivery The policy is to keep each service sparse and improve scalability.
In Spring Framework and Spring Boot, which everyone loves, Achieve lightweight development of services that handle message linkage The Spring Cloud Stream project is drawing attention.
Let's touch on message linkage using Spring Cloud Stream.
The completed code is here. Although not explained in the article, it comes with a test class.
The configuration diagram is below. If you don't understand while reading, please look back.
If you want to know the operation image, please read the chapter "Operation check" at the bottom of the page first.
The author's environment is as follows.
Spring Tool Suite 3
Version: 3.9.9.RELEASE
Build Id: 201906181741
Platform: Eclipse 2019-06 (4.12.0)
$ docker version
Client: Docker Engine - Community
Version: 19.03.2
API version: 1.40
Go version: go1.12.8
(Omission)
Server: Docker Engine - Community
Engine:
Version: 19.03.2
API version: 1.40 (minimum version 1.12)
Go version: go1.12.8
(Omission)
containerd:
Version: v1.2.6
(Omission)
runc:
Version: 1.0.0-rc8
(Omission)
docker-init:
Version: 0.18.0
(Omission)
$
$ java --version
java 9
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)
$
RabbitMQ is adopted because it is easy to introduce.
Pull the image from DockerHub and start the container with run. Click here for the RabbitMQ container manual (https://hub.docker.com/_/rabbitmq).
$ docker pull rabbitmq
//Start command
$ docker run -p 15672:15672 -p 5672:5672 rabbitmq:3-management
Once booted, you can access the management console. The URL is below. http://localhost:15672/
The ID and PW are guest: guest by default.
Spring Cloud Stream receives data from outside the service, such as REST API The service that links (OUTPUT) to the messaging platform is called Source.
The full code is here.
First, define the target queue name of the messaging infrastructure in application.properties.
spring.cloud.stream.bindings.output.destination=hello-processor
Then with the @EnableBinding annotation Associate the POJO class with the target queue of the messaging infrastructure.
In addition, DI the Source object Call the Source.output.send () method to send the message.
(Omitted)
@EnableBinding(Source.class)
public class HelloSourceApplication {
private final Source source;
public HelloSourceApplication(Source source) {
this.source=source;
}
(Omitted)
@PostMapping
public void tweet(@RequestBody Tweet tweet) {
source.output().send(MessageBuilder.withPayload(tweet).build());
}
public static class Tweet {
public String tweet;
}
}
Contrary to Source, it receives INPUT from the messaging platform. A service that links data to the back end Called Sink in Spring Cloud Stream.
The full code is here.
First, define the target queue name of the messaging infrastructure in application.properties.
spring.cloud.stream.bindings.input.destination=hello-sink
Then with the @EnableBinding annotation Associate the POJO class with the target queue of the messaging infrastructure. Also, with the @StreamListener annotation Link the message received from the queue directly with the DTO.
This time, the received DTO is output to the standard output and the process ends.
(Omitted)
@EnableBinding(Sink.class)
public class HelloSinkApplication {
(Omitted)
@StreamListener(Sink.INPUT)
public void print(Tweet tweet) {
System.out.println("Received " + tweet.tweet);
}
public static class Tweet {
public String tweet;
}
}
Received INPUT from the messaging platform A service that links (OUTPUT) to a messaging platform is called a Processor.
Click here for the full code (https://gitlab.com/kyosuke_yamagata/hello-messaging/blob/master/hello-processor/src/main/java/com/example/helloprocessor/HelloProcessorApplication.java)
First, define the target queue name of the messaging infrastructure in application.properties. In this example, the target queue name that the Sink service subscribes to is defined in OUTPUT. Also, as INPUT, the target queue name to which Source sends a message is defined.
spring.cloud.stream.bindings.output.destination=hello-sink
spring.cloud.stream.bindings.input.destination=hello-processor
Then with the @EnableBinding annotation Associate the POJO class with the target queue of the messaging infrastructure.
Furthermore, use the @StreamListener annotation to link the received message to the DTO. In addition, with @SendTo annotation The target queue to send the message and the message body are linked to the DTO which is the method return value.
As a result, when you receive the message The value is processed ("processing!" Is added after it), and the message is sent.
(Omitted)
@EnableBinding(Processor.class)
public class HelloProcessorApplication {
(Omitted)
@StreamListener(Processor.INPUT)
@SendTo(Processor.OUTPUT)
public Tweet transform(Tweet tweet) {
tweet.tweet += " processing!";
return tweet;
}
public static class Tweet {
public String tweet;
}
}
Run maven clean package for each project. Start each Jar generated under target as follows.
$ java -jar target/hello-source-0.0.1-SNAPSHOT.jar --server.port=8080
$ java -jar target/hello-sink-0.0.1-SNAPSHOT.jar --server.port=8082
$ java -jar target/hello-processor-0.0.1-SNAPSHOT.jar --server.port=8090
Send a POST request to Source with curl.
$ curl -v localhost:8080 -d '{"tweet":"Hello"}' -H 'Content-Type: application/json'
A message is output to the console that started Sink's Jar.
Received Hello processing!
Using Spring Boot, RabbitMQ and Spring Cloud Stream I learned how to design / implement microservice message linkage.
Please start and play with each service.
Stream Processing with RabbitMQ
Communication between microservices in Spring Cloud Stream
Recommended Posts