Spring Cloud Stream 消息驱动 实战

一、简介

Spring Cloud Stream 是一个构建消息驱动的微服务框架。通过 inputs(生产者) 和 outputs (消费者)来与 stream 中的 binder (绑定器)进行交互。

目前官方仅支持 Rabbit 和 Kafka

二、重要概念

2.1 Middleware

中间件,目前仅支持 rabbit 和 kafaka

2.2 Binder

消息中间件与应用之间的中间层,可通过配置文件动态改变消息类型

2.3 group

组,每个组对应一个队列,同组消费存在竞争,不同组消费不存在竞争。

不加分组时,重启时,之前错过的消息不会进行消费,加分组时则不会错过消息。

2.4 常用注解

  • @Input

标识输入通道,通过该输入通道接收的消息进入应用程序。

  • @Output

标识输出通道,通过该输出通道发送的消息进入消息中间件。

  • @StreamListener

监听队列,用于消费者队列的消息接收。

  • @EnableBinding

只信道 channel 和 exchange 绑定在一起

三、实例

pom.xml

<!-- 消费者生产者都要引入该依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>

3.1 消息生产者

  • application.yml
spring:
  application:
    name: stream-provider
  rabbitmq:  # 这里需要配置,否则会连接不上 Rabbit
    host: localhost
    port: 5672
    username: user
    password: password
  cloud:
    stream:
      bindings: # 服务整合处理
        output: # 生产者通道名称
          binder: rabbit1 # 设置要绑定的消息服务具体设置
          destination: studyExchange # 使用的交换机名称定义
          content-type: application/json # 设置消息类型,本地为json,文本设置为 text/plain

      binders: # 此处配置要绑定的 rabbitmq 服务信息
        rabbit1: # 表示自定义定义名称,用于 binding 整合
          type: rabbit # 消息组件类型
          environment: # 设置 rabbitmq 环境变量
            spring:
              rabbitmq:
                host: localhost
                port: 5672
                username: user
                password: password
  • service
@EnableBinding(Source.class) // 定义消息的推送,即 stream
@Slf4j
public class MessageProviderImpl implements MessageProvider {

    @Resource // 信道
    private MessageChannel output;

    @Override
    public String send() {
        String uuid = UUID.randomUUID().toString();
        output.send(MessageBuilder.withPayload(uuid).build());
        log.info("***********************uuid:" + uuid);
        return uuid;
    }
}

3.2 消息消费者

  • application.yml
spring:
  application:
    name: stream-consumer
  rabbitmq:
    host: localhost
    port: 5672
    username: user
    password: password
  cloud:
    stream:
      bindings: # 服务整合处理
        input: # 通道名称。消费者
          binder: rabbit1 # 设置要绑定的消息服务具体设置
          destination: studyExchange # 使用的交换机名称定义
          content-type: application/json # 设置消息类型,本地为json,文本设置为 text/plain

      binders: # 此处配置要绑定的 rabbitmq 服务信息
        rabbit1: # 表示自定义定义名称,用于 binding 整合
          type: rabbit # 消息组件类型
          environment: # 设置 rabbitmq 环境变量
            spring:
              rabbitmq:
                host: 172.16.10.82
                port: 5672
                username: user
                password: password
  • controller
@Component
@EnableBinding(Sink.class)
@Slf4j
public class ReceiveMessageController {
    @Value("${server.port}")
    private String port;

    @StreamListener(Sink.INPUT)
    public void receiveMessage (Message<String> message){

        log.info("消费者2:----------> " + message.getPayload()+"\t port:" + port);
    }
}

四、问题

4.1 重复消费

  • 原因

    默认分组 group 是不同的 组流水好不一样,默认不同组,则全部消费

  • 原理

    同一个交换机下,不同组会会被共同消费,导致重复消费,同一个组内才会发生竞争关系,只有一个可以消费

  • 解决方案

    设置相同组

4.2 消息丢失

  • 原因
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值