Construction and configuration of SpringCloud-Stream

Please check gitee for the following related project configuration https://gitee.com/xwb1056481167/spring-cloud

What is SpringCloudStream

The official website defines Spring cloud Stream as a framework for building message-driven microservices. The application interacts with the binder object in Spring Cloud Stream through inputs and outputs. Through our configuration, we bind (bind) and the binder object of Spring Cloud Stream is responsible for interacting with the message middleware. Therefore, we only need to figure out how to interact with Spring CloudStream to conveniently use the message-driven approach.

Why introduce

By using Spring Integration to connect the message broker middleware to achieve message-driven event-driven, Spring Cloud Stream provides personalized automated configuration implementations for some vendors’ message middleware products, applying the three types of publish-subscribe, consumer group, and partition. Core concepts. Only support RabbitMQ, Kafka Chinese help manual

https://m.wang1314.com/doc/webapp/topic/20971999.html

springCloudStream standard process

Component

Description

Middleware

Middleware, currently only supports RabbitMQ, Kafka

Binder

Binder is applied to the encapsulation between message middleware. At present, the Binder of Kafka and RabbitMQ is implemented. Through Binder, the middleware can be easily linked, and the message type can be dynamically changed (corresponding to the topic of Kafka and the exchange of RabbitMQ). These are all Can be achieved through configuration files

@Input

Annotation indicates an input channel, and messages received through this input channel enter the application

@Output

Represents the annotation output channel through which the published message will leave the application

@StreamListener

The listening queue is used for the message reception of the consumer's queue

@EnableBinding

Refers to the channel channel and exchange are bound together

Integration of consumers and providers

Message provider cloud-stream-rabbitmq-provider8801

1 、 pom.xml

<!-- stream rabbitmq -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
<!-- 添加rabbitmq的支持 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

2. The core configuration of yml

spring:
  cloud:
    stream:
      binders: #在此处配合要绑定的rabbitmq的服务信息
        defaultRabbit: #表示定义的名称,用于binding整合
          type: rabbit #消息组件类型
          environment: #设置rabbitmq的相关环境配置
            spring:
              rabbitmq:
                host: localhost
                port: 5672
                username: guest
                password: guest
      bindings: #服务的整合处理
        output: #这个名字是一个通道的名字
          destination: studyExchange #表示要使用的Exchange你名称定义
          content-type: application/json #设置消息类型,本次为json,文本则为"text/plain"
          binder: defaultRabbit #设置要绑定的额消息服务的具体设置

3. The main startup class

@SpringBootApplication
@EnableDiscoveryClient
public class StreamMQMain8801 {
    public static void main(String[] args) {
        SpringApplication.run(StreamMQMain8801.class,args);
    }
}

4. Core configuration sender

// 1、接口
public interface IMessageProvider {
    public String send();
}
//2、接口实现类
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.MessageBuilder;
import org.xwb.springcloud.service.IMessageProvider;
import javax.annotation.Resource;
import java.util.UUID;
/**
 * 定义消息的推送管道
 * 里面注入的内容都是message的,谨记不是注入dao、或其他什么,
 */
@EnableBinding(Source.class)
public class IMessageProviderImpl implements IMessageProvider {
    @Resource
    private MessageChannel output;
    @Override
    public String send() {
        String serial = UUID.randomUUID().toString();
        output.send(MessageBuilder.withPayload(serial).build());
        System.out.println("****************serial:"+serial);
        return serial;

    }
}
//3、controller发送
@RestController
public class SendMessageController {
    @Resource
    private IMessageProvider messageProvider;
    @GetMapping("/sendMessage")
    public String sendMessage() {
        return messageProvider.send();
    }
}

Note: @EnableBinding and MessageChannel are introduced in the jar package, both of which depend on cloud.stream.*

Message consumers 8802, 8803

The configuration of 8002 and 8003 are the same, only the port number is different, here it means that the configuration of 8002.8003 is the same as the
new module cloud-stream-rabbitmq-consumer8802

1 、 pom.xml

 <!-- stream rabbitmq -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
<!-- 添加rabbitmq的支持 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

2 、 l 配置

spring:
  cloud:
    stream:
      binders: #在此处配合要绑定的rabbitmq的服务信息
        defaultRabbit: #表示定义的名称,用于binding整合
          type: rabbit #消息组件类型
          environment: #设置rabbitmq的相关环境配置
            spring:
              rabbitmq:
                host: localhost
                port: 5672
                username: guest
                password: guest
      bindings: #服务的整合处理
        input: #这个名字是一个通道的名字
          destination: studyExchange #表示要使用的Exchange你名称定义
          content-type: application/json #设置消息类型,本次为json,文本则为"text/plain"
          binder: defaultRabbit #设置要绑定的额消息服务的具体设置

Note: bindings.input. Here, the consumer needs to get the message from the channel and input it into the sink to read it.
3. The main startup class

@SpringBootApplication
@EnableDiscoveryClient
public class StreamMQMain8802 {
    public static void main(String[] args) {
        SpringApplication.run(StreamMQMain8802.class, args);
    }
}

4. Message receiving and consumption

@Component
@EnableBinding(Sink.class)
public class ReceiveMessageListenerController {
    @Value("\${server.port}")
    private String serverPort;
    @StreamListener(Sink.INPUT)
    public void receiveMessage(@Payload String in, @Header(AmqpHeaders.CONSUMER_QUEUE) String queue) {
        System.out.println("消费者"+serverPort+"收到的消息为-->:"+in + " received from queue " + queue);
    }
}

Note: @EnableBinding and MessageChannel are introduced in jar packages, which are dependencies of cloud.stream.*.
Create the 8003 project in accordance with 8002.

test

Start 7001, 8801 producers, 8002, 8003 consumers, enter the get request in the address bar to send a message

http://localhost:8801/sendMessage

The peak change of rabbitmq

8802 and 8803 received message results

Group consumption and persistence

Question: The messages sent by 8801 will be consumed by 8802 and 8803. How to solve the problem.
Principle: When the microservice applications are placed in the same group, it can be guaranteed that the message will only be consumed by one of the applications once, and
different groups can be sub-Orpheid. , The same group will have a competitive relationship, and only one of them can consume.

Grouping

1. So the solution is to put them in the same group

spring:
  application:
    name: cloud-stream-customer #服务名
  cloud:
    stream:
      binders: #在此处配合要绑定的rabbitmq的服务信息
        defaultRabbit: #表示定义的名称,用于binding整合
          type: rabbit #消息组件类型
          environment: #设置rabbitmq的相关环境配置
            spring:
              rabbitmq:
                host: localhost
                port: 5672
                username: guest
                password: guest
      bindings: #服务的整合处理
        input: #这个名字是一个通道的名字
          destination: studyExchange #表示要使用的Exchange你名称定义
          content-type: application/json #设置消息类型,本次为json,文本则为"text/plain"
          binder: defaultRabbit #设置要绑定的额消息服务的具体设置
          group: consumerA

Join the same group: group: consumerA can avoid repeated consumption

Endurance

If one of 8802 and 8803 is configured with grouping, and the other is cancelled, the consumer configured with grouping will automatically consume the message sent by the 8801 sender after the consumer restarts. Make the message persistent.
Proof: The group must be configured

Guess you like

Origin blog.csdn.net/www1056481167/article/details/113605633