springcloud中stream的使用

pom文件

<dependencies>
    <!-- 创建工程需要的两个依赖 -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!-- web 工程 -->
    <dependency>
        <groupId>com.imooc.ecommerce</groupId>
        <artifactId>xyc-commerce-mvc-config</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.kafka</groupId>
        <artifactId>spring-kafka</artifactId>
        <version>2.5.0.RELEASE</version>
    </dependency>
    <!-- SpringCloud Stream-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-stream</artifactId>
    </dependency>
    <!-- SpringCloud Stream + Kafka -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-stream-binder-kafka</artifactId>
    </dependency>
    <!-- SpringCloud Stream + RocketMQ -->
    <!--        <dependency>-->
    <!--            <groupId>com.alibaba.cloud</groupId>-->
    <!--            <artifactId>spring-cloud-starter-stream-rocketmq</artifactId>-->
    <!--        </dependency>-->
</dependencies>
<dependencyManagement>
    <dependencies>
        <!-- spring cloud 依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <!-- spring cloud alibaba 依赖 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${spring-cloud-alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

yml配置文件

server:
  port: 8006
  servlet:
    context-path: /ecommerce-stream-client

spring:
  application:
    name: e-commerce-stream-client
  cloud:
    nacos:
      # 服务注册发现
      discovery:
        enabled: true # 如果不想使用 Nacos 进行服务注册和发现, 设置为 false 即可
        server-addr: 192.168.94.129:8848
        namespace: d8fa475f-a1df-4cd3-acbf-e9d6df0ca59f
        metadata:
          management:
            context-path: ${server.servlet.context-path}/actuator
    # 消息驱动的配置
    stream:
      # SpringCloud Stream + Kafka
      kafka:
        binder:
          brokers: 192.168.94.129:9092
          auto-create-topics: true  # 如果设置为false, 就不会自动创建Topic,
          # 你在使用之前需要手动创建好
      # SpringCloud Stream + RocketMQ
      #      rocketmq:
      #        binder:
      #          name-server: 127.0.0.1:9876
      # 开启 stream 分区支持
      instanceCount: 1  # 消费者的总数
      instanceIndex: 0  # 当前消费者的索引
      bindings:
        # 默认发送方
        output:      # 这里用 Stream 给我们提供的默认 output 信道
          destination: ecommerce-stream-client-default    
          # 消息发往的目的地, Kafka 中就是 Topic
          content-type: text/plain    # 消息发送的格式, 接收端不用指定格式, 但是发送端要
          # 消息分区
          producer:
            # partitionKeyExpression: payload.author  # 分区关键字, 
            #payload 指的是发送的对象, author 是对象中的属性
            partitionCount: 1   # 分区大小
            # 使用自定义的分区策略, 注释掉 partitionKeyExpression
            partitionKeyExtractorName: qinyiPartitionKeyExtractorStrategy
            partitionSelectorName: qinyiPartitionSelectorStrategy
        # 默认接收方
        input:      # 这里用 Stream 给我们提供的默认 input 信道
          destination: ecommerce-stream-client-default
          group: e-commerce-qinyi-default
          # 消费者开启分区支持
          consumer:
            partitioned: true

        # Qinyi 发送方
        qinyiOutput:
          destination: ecommerce-stream-client-qinyi
          content-type: text/plain
        # Qinyi 接收方
        qinyiInput:
          destination: ecommerce-stream-client-qinyi
          group: e-commerce-qinyi-qinyi

  # spring-kafka 的配置
  kafka:
    bootstrap-servers: 192.168.94.129:9092
    producer:
      retries: 3
    consumer:
      auto-offset-reset: latest
#  sleuth:
#    sampler:
#      # ProbabilityBasedSampler 抽样策略
#      probability: 1.0  # 采样比例, 1.0 表示 100%, 默认是 0.1
#      # RateLimitingSampler 抽样策略
#      rate: 100  # 每秒间隔接受的 trace 量
#  zipkin:
#    sender:
#      type: kafka # 默认是 http
#    base-url: http://localhost:9411/

# 暴露端点
management:
  endpoints:
    web:
      exposure:
        include: '*'
  endpoint:
    health:
      show-details: always

消息的传递对象

@Data
@AllArgsConstructor
@NoArgsConstructor
public class QiyiMessage {

    private Integer id;

    private String projectName;

    private String org;

    private String author;

    private String version;

    /**
     * 返回一个默认消息,方便使用
     * @return
     */
    public static QiyiMessage defaultMessage()
    {
        return new QiyiMessage(
                1,
                "e-commerce-stream-client",
                "imooc-com",
                "Qiyi",
                "1.0"
        );
    }
}

自定义分区策略

/**
 * ProjectName xyc-commerce-springcloud
 * 从message中提取 partition key的策略
 * @author xieyucan
 * <br>CreateDate 2022/9/14 14:07
 */
@Slf4j
@Component
public class QinyiPartitionKeyExtractorStrategy implements PartitionKeyExtractorStrategy {

    @Override
    public Object extractKey(Message<?> message) {
        QiyiMessage message1 = JSON.parseObject(message.getPayload().toString(), QiyiMessage.class);
        String key = message1.getProjectName();
        log.info("SpringCloud Stream QinYi partition Key:[{}]",key);
        return key;
    }
}

分区选择名称

/**
 * ProjectName xyc-commerce-springcloud
 * 决定message 或者 payload 发送到哪个分区的策略
 * @author xieyucan
 * <br>CreateDate 2022/9/14 14:07
 */
@Slf4j
@Component
public class QinyiPartitionSelectorStrategy implements PartitionSelectorStrategy {
    /**
     * 选择分区的策略
     * @param key
     * @param partitionCount
     * @return
     */
    @Override
    public int selectPartition(Object key, int partitionCount) {
        int partition=key.toString().hashCode()%partitionCount;
        log.info("SpringCloud Stream QinYi Selector info:[{}],[{}],[{}]",
                key.toString(),partitionCount,partition);
        return partition;
    }
}

默认发送方

@Slf4j
@EnableBinding(Source.class)
public class DefaultSendService {

    private final Source source;

    public DefaultSendService(Source source) {
        this.source = source;
    }

    /**
     * 使用默认的输出信道发送消息
     * @param message
     */
    public void sendMessage(QiyiMessage message)
    {
        String _message= JSON.toJSONString(message);
        log.info("in DefaultSendService send message:[{}]",message);
        //spring message,统一消息的编程模型,是stream组件的重要组成部分之一
        source.output().send(MessageBuilder.withPayload(_message).build());

    }
}

默认接收方

/**
 * ProjectName xyc-commerce-springcloud
 *
 * @author xieyucan
 * <br>CreateDate 2022/9/14 11:17
 */
@Slf4j
@EnableBinding(Sink.class)
public class DefaultReceiveService {

    /**
     * 使用默认的输入信道接收消息
     * @param payload
     */
    @StreamListener(Sink.INPUT)
    public void receiveMessage(Object payload)
    {
        log.info("in DefaultReceiveService consume message start");
        QiyiMessage message=JSON.parseObject(payload.toString(), QiyiMessage.class);
        //消费消息
        log.info("in DefaultReceiveService consume message success:[{}]",JSON.toJSONString(message));
    }
}

自定义发送和接收

自定义输入信道

/**
 * ProjectName xyc-commerce-springcloud
 * 自定义输入信道
 * @author xieyucan
 * <br>CreateDate 2022/9/14 11:37
 */
public interface QinyiSink {

    String INPUT="qinyiInput";

    @Input(QinyiSink.INPUT)
    SubscribableChannel qinyiInput();
}

自定义输出信道

/**
 * ProjectName xyc-commerce-springcloud
 * 自定义输出信道
 * @author xieyucan
 * <br>CreateDate 2022/9/14 11:28
 */
public interface QinyiSource {

    String OUTPUT="qinyiOutput";

    /**
     * 输出信道的名称是 qinyiOutput,需要使用stream 绑定在yml文件中声明
     * @return
     */
    @Output(QinyiSource.OUTPUT)
    MessageChannel qinyiOutput();
}

使用自定义的通信信道 QinyiSource 实现消息发送

/**
 * ProjectName xyc-commerce-springcloud
 * 使用自定义的通信信道 QinyiSource 实现消息发送
 * @author xieyucan
 * <br>CreateDate 2022/9/14 11:32
 */
@Slf4j
@EnableBinding(QinyiSource.class)
public class QinyiSendService {

    private final QinyiSource qinyiSource;

    public QinyiSendService(QinyiSource qinyiSource) {
        this.qinyiSource = qinyiSource;
    }

    /**
     * 使用自定义输出信道发送消息
     * @param message
     */
    public void sendMessage(QiyiMessage message)
    {
        String _message=JSON.toJSONString(message);
        log.info("in QinyiSendService send message:[{}]",_message);
        qinyiSource.qinyiOutput().send(MessageBuilder.withPayload(_message).build());
    }
}

使用自定义的输入信道接收消息

/**
 * ProjectName xyc-commerce-springcloud
 * 使用自定义的输入信道接收消息
 * @author xieyucan
 * <br>CreateDate 2022/9/14 11:42
 */
@Slf4j
@EnableBinding(QinyiSink.class)
public class QinyiReceiveService {

    /**
     * 使用自定义的输入信道接收消息
     * @param payload
     */
    @StreamListener(QinyiSink.INPUT)
    public void receiveMessage(@Payload Object payload)
    {
        log.info("in QinyiReceiveService consume message start");
        QiyiMessage message = JSON.parseObject(payload.toString(), QiyiMessage.class);
        log.info("in QinyiReceiveService consume message success:[{}]",JSON.toJSONString(message));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Stream 是一个构建消息驱动微服务的框架,它基于 Spring Boot 和 Spring Integration,通过简单声明式模型来实现消息的发送和接收。Spring Cloud Stream 可以与多种消息间件集成,如 RabbitMQ、Kafka 等。 使用 Spring Cloud Stream 的步骤如下: 1. 添加依赖 在 pom.xml 添加 Spring Cloud Stream 相关的依赖,如下: ``` <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream</artifactId> </dependency> ``` 2. 创建消息处理器 创建一个消息处理器,用于接收和处理消息,例如: ``` @Component public class MessageHandler { @StreamListener(Sink.INPUT) public void handleMessage(String message) { System.out.println("Received message: " + message); } } ``` 这个消息处理器使用 `@StreamListener` 注解来监听 `Sink.INPUT`,表示接收来自输入通道的消息,并打印出来。 3. 配置绑定器 在配置文件配置绑定器,用于将应用程序与消息间件连接起来。例如,如果要使用 RabbitMQ,可以这样配置: ``` spring.cloud.stream.bindings.input.destination=myQueue spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest ``` 这里配置了输入通道的目的地为 `myQueue`,以及 RabbitMQ 的连接信息。 4. 发送消息 使用 `MessageChannel` 来发送消息,例如: ``` @Autowired private MessageChannel output; public void sendMessage(String message) { output.send(MessageBuilder.withPayload(message).build()); } ``` 这里注入了一个 `output` 的 `MessageChannel`,通过它发送消息,例如: ``` sendMessage("Hello, world!"); ``` 这样就可以将一条消息发送到 `myQueue` 队列。 以上就是使用 Spring Cloud Stream 的基本步骤。需要注意的是,消息的发送和接收是基于通道(Channel)的,而通道是由绑定器(Binder)来创建和管理的。因此需要在配置文件配置绑定器相关的信息,才能正常发送和接收消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值