Use of spring cloud stream
1, Introduction to SpringCloud Stream
In the actual development, there are various kinds of message processing middleware (MQ), but if you learn all MQ, the learning cost is too high, and the emergence of spring cloud stream can ignore the difference of message middleware used at the bottom, reduce the switching cost, and unify the programming model of message.
Spring Cloud Stream is a framework for building highly scalable event-driven microservices connected with shared messaging systems.
The framework provides a flexible programming model built on already established and familiar Spring idioms and best practices, including support for persistent pub/sub semantics, consumer groups, and stateful partitions.
Spring Cloud Stream is a framework for building highly scalable event driven microservices connected to shared messaging systems.
The framework provides a flexible programming model based on established and familiar Spring idioms and best practices, including support for persistent publish / sub semantics, consumer groups, and stateful partitioning.
1.Stream usage
Interaction mode:
- The application interacts with the binder object in Spring Cloud Stream through inputs or outputs.
- After the binding is configured, the Spring Cloud Stream's binder object interacts with the message middleware.
Therefore, we only need to interact with Spring Cloud Stream, and then this middleware will help us transform and interact.
Using Spring Integration to connect the message broker middleware to achieve message event driven.
Currently, only RabbitMQ and Kafka are supported
Spring Cloud Stream guide in Chinese
2, About Binder
Binder, as the middle layer, realizes the isolation between application and message middleware details (corresponding to the exchange of rabbitMQ and the Topic of kafka)
Input in binder corresponds to message consumer
Output in binder corresponds to message producer
3, Stream common comments
@Input
Annotation identifies the input channel through which information received enters the application
@Output
Annotation identifies the output channel through which published messages leave the application
@StreamListener
Listening queue, used for receiving queue messages of consumers
@EnableBinding
Channel and exchange are bound together
4, Stream operation
1. Build message producers
1. Building sub modules
2. Modify pom file
Added spring cloud starter stream rabbit
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency> <!--Basic configuration--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
3. Preparation of yml documents
server: port: 8801 spring: application: name: cloud-stream-provider cloud: stream: binders: # Configure the service information of rabbitmq to be bound here; defaultRabbit: # Represents the name of the definition used for binding integration type: rabbit # Message component type environment: # Setting up the relevant environment configuration of rabbitmq spring: rabbitmq: host: 192.168.1.50 port: 5672 username: guest password: guest bindings: # Integration of services output: # This name is the name of a channel destination: studyExchange # Represents the Exchange name definition to use content-type: application/json # Set the message type. This time, it is json, and the text is "text/plain" binder: defaultRabbit # Set the specific settings of the message service to be bound eureka: client: # Configuration of Eureka registration by client service-url: defaultZone: http://localhost:7001/eureka instance: lease-renewal-interval-in-seconds: 2 # Set heartbeat interval (default is 30 seconds) lease-expiration-duration-in-seconds: 5 # If the interval of 5 seconds is exceeded now (the default is 90 seconds) instance-id: send-8801.com # Show host name in message list prefer-ip-address: true # Access path changed to IP address
binder: defaultRabbit reports red here, but does not affect the operation
4. Main method of compilation
@SpringBootApplication public class StreamProviderMain8801 { public static void main(String[] args){ SpringApplication.run(StreamProviderMain8801.class,args); } }
5. Write service
public interface IMessageService { public String send(); }
@EnableBinding(Source.class)//Define push pipeline for messages @Slf4j public class MessageServiceImpl implements IMessageService { @Resource private MessageChannel output; @Override public String send() { String serial = UUID.randomUUID().toString(); output.send(MessageBuilder.withPayload(serial).build()); log.info("*********serial:" + serial); return null; } }
6. Write controller
@RestController public class MessageController { @Resource private IMessageService messageService; @GetMapping("/sendmsg") public String send() { return messageService.send(); } }
2. Build message consumers
1. Building sub modules
2. Modify pom
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--Basic configuration--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
3. Write yml
Two consumers are opened here. Only the name and port number of eureka on the face need to be changed
server: port: 8802 spring: application: name: cloud-stream-consumer cloud: stream: binders: # Configure the service information of rabbitmq to be bound here; defaultRabbit: # Represents the name of the definition used for binding integration type: rabbit # Message component type environment: # Setting up the relevant environment configuration of rabbitmq spring: rabbitmq: host: 192.168.1.50 port: 5672 username: guest password: guest bindings: # Integration of services input: # This name is the name of a channel destination: studyExchange # Represents the Exchange name definition to use content-type: application/json # Set the message type. This time it is the object json. If it is text, set "text/plain" binder: defaultRabbit # Set the specific settings of the message service to be bound eureka: client: # Configuration of Eureka registration by client service-url: defaultZone: http://localhost:7001/eureka instance: lease-renewal-interval-in-seconds: 2 # Set heartbeat interval (default is 30 seconds) lease-expiration-duration-in-seconds: 5 # If the interval of 5 seconds is exceeded now (the default is 90 seconds) instance-id: receive-8802.com # Show host name in message list prefer-ip-address: true # Access path changed to IP address
Note that consumers use input
bindings: # Integration of services input: # This name is the name of a channel destination: studyExchange # Represents the Exchange name definition to use content-type: application/json # Set the message type. This time it is the object json. If it is text, set "text/plain" binder: defaultRabbit # Set the specific settings of the message service to be bound
4. Main method of compilation
@SpringBootApplication public class StreamConsumerMain8802 { public static void main(String[] args){ SpringApplication.run(StreamConsumerMain8802.class,args); } }
5. Create message add component Controller
@EnableBinding(Sink.class) public class ReciveMessageController { @Value("${server.port}") private String serverPort; @StreamListener(Sink.INPUT) //import org.springframework.messaging.Message; public void recive(Message<String> message) { System.out.println("consumer"+serverPort+"\t Information received:"+message.getPayload()); } }
5, Stream message grouping
1. Repeated consumption
After the above operations are completed, it is found that if a message is sent, both sides will receive it, that is, a message will be consumed by two consumers at the same time
In actual projects, if the nature of consumption is the same, we should not consume both, but compete for one consumption
At this time, messages need to be grouped. The same group competes for messages and different groups receive them
2. Message persistence
If a server is not grouped, if the server is shut down, the last message will not be received;
If the packet is used and the service is restarted, it can receive the last message. This is message persistence
3. Enable grouping mode
Overwrite yml file
bindings: # Integration of services input: # This name is the name of a channel destination: studyExchange # Represents the Exchange name definition to use content-type: application/json # Set the message type. This time it is the object json. If it is text, set "text/plain" binder: defaultRabbit # Set the specific settings of the message service to be bound group: GroupA
When on, polling mode is on by default
6, Summary
1. Learning summary
Spring Cloud Stream uses binder interaction, which can ignore the layer message middleware, and then help us transform and interact.
Currently, only RabbitMQ and Kafka are supported
2. Precautions
When configuring the yml configuration, the binder: defaultRabbit reports red here, but does not affect the operation