【八】Spring Cloud Stream

目前 Spring Cloud Stream 支持两种中间件 rabbitMQ, kafka.

1. 简单利用cloud Stream进行收发信息

1.1 首先启动 rabbitmq作为mq

rabbitmqServer.sh start

1.2 新建项目,引入对应的POM依赖


            org.springframework.cloud
            spring-cloud-stream-binder-rabbit
        

 
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                ${spring-cloud.version}
                pom
                import
            
        
    

1.3 增加配置文件

#注意管道的名字需要变化, example-topic-output/example-topic-input
spring.cloud.stream.bindings.example-topic-output.destination=chenhuallong
spring.cloud.stream.bindings.example-topic-input.destination=chenhuallong
spring.cloud.stream.bindings.input.group=Service-lemon

spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

1.4 Steam 中Binder的定位,Exchange的定位

steam主要的进行隔离的架构如下:

image.png

stream中默认已经有 Source.class sink.class两个 交换器了。

1.5 自己定义exchagne

/**
 * 自定义自己的通道queue
 */
public interface LemonMessageTopic {


    String LEMON_OUTPUT = "example-topic-output";
    String LEMON_INPUT = "example-topic-input";

    @Output(LEMON_OUTPUT)
    MessageChannel output();

    @Input(LEMON_INPUT)
    SubscribableChannel input();
    
}
1.5.1 在主类上将exchange进行注入
@EnableBinding(LemonMessageTopic.class)
@SpringBootApplication
public class DemoSpringcloudStreamApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoSpringcloudStreamApplication.class, args);
    }

}

1.6 定义收取消息的代码类

@Component
public class MessageReceiver {


    @StreamListener(LemonMessageTopic.LEMON_INPUT)
    public void  receive(Object message){

        System.out.println("messageReceive :" +message.toString());
    }
}

1.7 定义发送消息的代码类


@RestController
public class MessageController {

    @Autowired
    private LemonMessageTopic topic;


    @GetMapping("/send")
    public Object sendMessage() {

        String message = "hello ,this is my first message";
        topic.output().send(org.springframework.messaging.support.MessageBuilder.withPayload(message).build());

        return "success";
    }
}

1.8 观察rabbitmQ

image.png
image.png
image.png

2. 使用消息订阅模式

image.png

2.1 再新建一个项目,和上一个完全一样,然后启动

image.png

2.2 发送一条信息,观察两个项目都可以收到

image.png

3. 消息分组

为了防止 这种消息被所有人都消费掉,所以采用消息分组,只有在同一个消费组中,且同一个消费组中,只能有一个实例进行消费,保证不会多次消费。

spring.cloud.stream.bindings.input.group

image.png

在准备消费同一信息的实例中,增加相同的分组

spring.cloud.stream.bindings.example-topic-input.group=Service-lemon

后续就变成了遍历进行轮询消化对应的接口

4. 消息分区

对于一些特殊场景,除了要保证单一实例消费之外,还希望那些具备相同特征的消息都能够被同一个实例进行消费。这时候我们就需要对消息进行分区处理

4.1 消费端需要更改的配置如下

# 打开消费者分区功能
spring.cloud.stream.bindings.input.consumer.partitioned=true
#当前消费者的总实例数量
spring.cloud.stream.instanceCount=2
# 当前实例索引号
spring.cloud.stream.instanceIndex=0

4.2 修改生产者的配置

# 通过消息规则配置SPEL生成分区间
spring.cloud.stream.bindings.output.producer.partitionKeyExpression=payload
# 指定消息分区的数量
spring.cloud.stream.bindings.output.producer.partitionCount=2

5. 通过消息内容分发给不同消费处理逻辑

5.1 生产端代码改造

 @GetMapping("/sendMessage")
        public String messageWithMQ(@RequestParam String message) {
            testTopic.output().send(MessageBuilder.withPayload(message).setHeader("version", "1.0").build());
            testTopic.output().send(MessageBuilder.withPayload(message).setHeader("version", "2.0").build());
            return "ok";
        }

5.2 消费端代码改造

 @StreamListener(value = TestTopic.INPUT, condition = "headers['version']=='1.0'")
        public void receiveV1(String payload, @Header("version") String version) {
            log.info("Received v1 : " + payload + ", " + version);
        }

        @StreamListener(value = TestTopic.INPUT, condition = "headers['version']=='2.0'")
        public void receiveV2(String payload, @Header("version") String version) {
            log.info("Received v2 : " + payload + ", " + version);
        }

6. 自动失败重试机制

默认情况下Spring Cloud Stream会重试3次,我们也可以通过配置的方式修改这个默认配置,比如下面的配置可以将重试次数调整为1次。

spring.cloud.stream.bindings.example-topic-input.consumer.max-attempts=1

你可能感兴趣的:(【八】Spring Cloud Stream)