spring-cloud-stream

Table of Contents of Series Articles

Chapter 1 Application of Java Thread Pool Technology
Chapter 2 Application of CountDownLatch and Semaphone
Chapter 3 Introduction to Spring Cloud< a i=3>Chapter 4 Spring Cloud Netflix - EurekaChapter 5 Spring Cloud Netflix - RibbonChapter 6 Spring Cloud - OpenFeign< a i=6>Chapter 7 Spring Cloud's GateWayChapter 8 Spring Cloud Netflix's HystrixChapter 9 Code Management GitLab UsageChapter 10 Nacos discovery of Spring Cloud AlibabaChapter 11 Nacos Config of Spring Cloud AlibabaChapter 12 Sentinel of Spring Cloud AlibabaChapter 16 spring-cloud-streamChapter 15 RabbitMQ Delay QueueChapter 14 RabbitMQ ApplicationChapter 13 JWT












Insert image description here


Preface

https://github.com/spring-cloud/spring-cloud-stream-binder-rabbit
Official definition Spring Cloud Stream is a framework for building message-driven microservices. Applications interact with binder objects in Spring Cloud Stream through inputs or outputs. Binding is done through our configuration, and the binder object of Spring Cloud Stream is responsible for interacting with the message middleware.

SpringCloud stream uses Spring Integration to connect the message broker middleware to achieve message event driving. Spring Cloud Stream provides personalized automated configuration implementation for some vendors' message middleware products, citing the three core concepts of publish-subscribe, consumer group, and partition.

Stream allows us to no longer pay attention to the details of specific MQ. We only need to use an adaptive binding method to automatically switch between various MQs. In general, Stream can shield the differences in the underlying message middleware and reduce switching. Cost, is the programming model for Unified Messaging.

1. Stream design ideas

Insert image description here
Insert image description here

  • Binder: Very convenient connection middleware, shielding differences
  • Channel: Channel is an abstraction of Queue. In the message communication system, it is the medium for storage and forwarding. The queue is configured through Channel.
  • Source and Sink: It can be simply understood that the reference object is Spring Cloud Stream itself, publishing messages from Stream is output, and receiving messages is input.

2. Commonly used annotations for coding

Insert image description here

composition illustrate
Middleware Middleware, currently only supports RabbitMQ and Kafka
Binder Binder is the encapsulation between the application and the message middleware. Currently, the Binder of Kafka and RabbitMQ is implemented. The middleware can be easily connected through BInder, and the message type can be dynamically changed (corresponding to the topic of Kafka and the exchange of RabbitMQ). These All can be achieved through configuration files.
@Input The annotation identifies the input channel through which messages received enter the application.
@Output Annotation identifies the output channel through which published messages will leave the application
@StreamListener Listening queue, used to receive messages from consumer queues
@EnableBinding Refers to the channel channel and exchange being bound together.

3. Encoding steps

3.1. Add dependencies

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>

3.2. Modify configuration file

server:
  port: 8088

spring:
  cloud:
    stream:
      binders: #需要绑定的rabbitmq的服务信息
        defaultRabbit:  #定义的名称,用于bidding整合
          type: rabbit  #消息组件类型
          environment:  #配置rabbimq连接环境
            spring:
              rabbitmq:
                host: localhost   #rabbitmq 服务器的地址
                port: 5672           #rabbitmq 服务器端口
                username: tiger       #rabbitmq 用户名
                password: tiger       #rabbitmq 密码
                virtual-host: tiger_vh  #虚拟路径
      bindings:        #服务的整合处理
        saveOrderOutput:    #这个是消息通道的名称 --->保存订单输出通道
          destination: exchange-saveOrder     #exchange名称,交换模式默认是topic;把SpringCloud stream的消息输出通道绑定到RabbitMQ的exchange-saveOrder交换器。
          content-type: application/json      #设置消息的类型,本次为json
          default-binder: defaultRabbit
          group: saveOrderGroup               #分组
        saveOrderInput: #生产者绑定,这个是消息通道的名称---> 保存订单输入通道
          destination: exchange-saveOrder     #exchange名称,交换模式默认是topic;把SpringCloud stream的消息输出通道绑定到RabbitMQ的exchange-saveOrder交换器。
          content-type: application/json      #设置消息的类型,本次为json
          default-binder: defaultRabbit
          group: saveOrderGroup               #分组

3.3. Production

/**
 * 订单消息输出通道处理器
 */
@Component
public interface OrderOutputChannelProcesor {
    
    
    @Output("saveOrderOutput")
    MessageChannel saveOrderOutput();
}

@Slf4j
@EnableBinding(OrderOutputChannelProcesor.class)
public class OrderMessageProducer {
    
    
    @Autowired
    @Output("saveOrderOutput")
    private MessageChannel messageChannel;

    public void sentMsg(UserInfo userInfo){
    
    
        messageChannel.send(MessageBuilder.withPayload(userInfo).build());
        log.info("消息发送成功:" + userInfo);
    }
}

3.4. Consumption

/**
 * 订单消息输入通道处理器
 */
@Component
public interface OrderInputChannelProcesor {
    
    
    @Input("saveOrderInput")
    SubscribableChannel saveOrderInput();
}
@Slf4j
@EnableBinding(OrderInputChannelProcesor.class)
public class OrderMessageConsumer {
    
    
    @StreamListener("saveOrderInput")
    public void receiveMsg(Message<UserInfo> userInfoMessage){
    
    
        log.info("接收消息成功:" + userInfoMessage.getPayload());
    }
}

3.5. Delay queue

Install the delayed queue plugin:
https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases/download/3.11.1/rabbitmq_delayed_message_exchange-3.11.1 .ez
Download and unzip, go to the plugins directory, and execute the following command:

rabbitmq-plugins enable rabbitmq_delayed_message_exchange

3.5.1. Modify configuration file

server:
  port: 8088

spring:
  cloud:
    stream:
      binders: #需要绑定的rabbitmq的服务信息
        defaultRabbit:  #定义的名称,用于bidding整合
          type: rabbit  #消息组件类型
          environment:  #配置rabbimq连接环境
            spring:
              rabbitmq:
                host: localhost   #rabbitmq 服务器的地址
                port: 5672           #rabbitmq 服务器端口
                username: tiger       #rabbitmq 用户名
                password: tiger       #rabbitmq 密码
                virtual-host: tiger_vh  #虚拟路径
      bindings:        #服务的整合处理
        saveOrderOutput:    #这个是消息通道的名称 --->保存订单输出通道
          destination: exchange-saveOrder-delay     #exchange名称,交换模式默认是topic;把SpringCloud stream的消息输出通道绑定到RabbitMQ的exchange-saveOrder交换器。
          content-type: application/json      #设置消息的类型,本次为json
          default-binder: defaultRabbit
          group: saveOrderGroup               #分组
        saveOrderInput: #生产者绑定,这个是消息通道的名称---> 保存订单输入通道
          destination: exchange-saveOrder-delay     #exchange名称,交换模式默认是topic;把SpringCloud stream的消息输出通道绑定到RabbitMQ的exchange-saveOrder交换器。
          content-type: application/json      #设置消息的类型,本次为json
          default-binder: defaultRabbit
          group: saveOrderGroup               #分组
      rabbit:
        bindings: #服务的整合处理
          saveOrderOutput:    #这个是消息通道的名称 --->保存订单输出通道
            producer:
              delayed-exchange: true
          saveOrderInput:
            consumer:
              delayed-exchange: true

3.5.2. Production end

@Slf4j
@EnableBinding(OrderOutputChannelProcesor.class)
public class OrderMessageProducer {
    
    
    @Autowired
    @Output("saveOrderOutput")
    private MessageChannel messageChannel;

    public void sentMsg(UserInfo userInfo){
    
    
        messageChannel.send(MessageBuilder.withPayload(userInfo).setHeader("x-delay", 5000).build());
        log.info("消息发送成功:" + userInfo);
    }
}

3.5.2. Message confirmation mechanism consumer side

rabbit:
  bindings: #服务的整合处理
    saveOrderInput:
      consumer:
        acknowledge-mode: MANUAL #手动确认
@StreamListener("saveOrderInput")
public void receiveMsg(Message<UserInfo> userInfoMessage){
    
    

    log.info("接收消息成功:" + userInfoMessage.getPayload());
    Channel channel = (Channel) userInfoMessage.getHeaders().get(AmqpHeaders.CHANNEL);
    Long delieverTag = (Long) userInfoMessage.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
    /*
     * deliveryTag:Channel的消息投递的唯一标识符。
     * multiple:是否否定应答多条消息。如果设置为true,则否定应答带指定deliveryTag的消息及该deliveryTag之前的多条消息;
     * 如果设置为false,则仅否定应答带指定deliveryTag的单条消息。
     * requeue:被否定应答的消息是否重入队列。如果设置为true,则消息重入队列;
     * 如果设置为false,则消息被丢弃或发送到死信Exchange。
     */
    try {
    
    
        channel.basicAck(delieverTag,true);
    } catch (IOException e) {
    
    
        e.printStackTrace();
    }
}

Define the switch type as direct

rabbit:
  bindings: #服务的整合处理
    saveOrderInput:
      consumer:
        bindingRoutingKey: orderRoutingKey
        bindQueue: true
        exchangeType: direct
    saveOrderOutput:
      producer:
        routingKeyExpression: orderRoutingKey
        exchangeType: direct

Summarize

spring-cloud-stream currently supports RabbitMQ and Kafka, and is seamlessly integrated with spring-cloud, which is very convenient.

Guess you like

Origin blog.csdn.net/s445320/article/details/134360837