简介

Spring Cloud Stream 是一个轻量级消息驱动微服务框架,旨在简化与消息中间件(如 Kafka、RabbitMQ 等)的集成,支持消息的发布和订阅模式。它提供了一种基于 Spring 编程模型的方式(即自动依赖注入和强调通过注解来完成功能的封装),使得构建可扩展和灵活的消息驱动应用变得更加简单。

特点

  • 消息中间件支持:Spring Cloud Stream 支持多种消息中间件,包括 Kafka、RabbitMQ 等,用户可以通过简单的配置切换不同的消息系统而不需修改业务逻辑代码。
  • 绑定模型:Spring Cloud Stream 通过“绑定”抽象层来简化与消息中间件的交互。开发者不需要直接处理底层的消息中间件,而是通过定义“绑定器”来与消息源(如 Kafka、RabbitMQ)进行通信。
  • 消息驱动:提供了事件驱动和流处理的支持。
  • 简化配置:通过 Spring Boot 的自动配置,Spring Cloud Stream 可以通过简单的属性配置来进行消息系统的连接和消息传递。
  • 可扩展性:Spring Cloud Stream 支持开发者使用自定义的消息转换器、处理器等组件,使得消息传递过程能够根据具体业务需求进行灵活定制。
  • 与 Spring Cloud 集成:在 Spring.io 中是SpringCloud下的顶级项目,可以与SpringCloud其它项目无缝集成,适用于微服务架构。

核心模块

  • Binder:用于实现消息系统的具体接入,例如 Kafka、RabbitMQ 等。
  • Channel:消息的通道,通过 @StreamListener 注解来监听通道,接收和处理消息。消息生产者和消费者都是通过Channel来处理消息的。
  • Producer & Consumer:生产者和消费者,分别负责消息的发布和订阅。Spring Cloud Stream 提供了注解 @Output 和 @Input 来标注消息通道的生产与消费。

最佳实践

pom


<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.7.6</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2021.0.6</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>${spring-boot.version}</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <version>2021.0.6.2</version>
    </dependency>
    <!-- SpringCloud Alibaba Nacos Config -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        <version>2021.0.6.2</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-stream-binder-kafka</artifactId>
    </dependency>
</dependencies>
  • 核心依赖:spring-cloud-stream-binder-kafka
  • 其中已经包含了 spring-kafka 这个依赖,无需重复引入
  • 从其依赖关系来看,SpringCloudStream 的实现引用了 SpringIntegration 这个框架,这也是一个比较有趣的框架,是Spring的顶级框架,感兴趣的可以参看 SpringIntegration漫谈 了解 SpringIntegration 框架的设计立场和实现思路。

yml


spring:
  kafka:
    consumer:
      max-poll-records: 50
      bootstrap-servers: 192.168.1.92:9092
  • max-poll-records:指定消费者每次从 Kafka 拉取(poll)时能够获取的最大消息数量。
  • bootstrap-servers:kafka的server端的连接地址。注意需要将kafka-server 的 server.properties 配置文件中的 listeners=PRIVATE://0.0.0.0:9092 并且 advertised.listeners=PRIVATE://192.168.1.92:9092 ,否则无法对外提供服务。

定义消息通道


import org.springframework.cloud.stream.annotation.Input;
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.SubscribableChannel; public interface AircraftChannel {     /**
     * kafka topic  名称
     */
    String TOPIC = KAFKA_TOPIC_NGH_AIRCRAFT;     /**
     * 定义消费者接收消息的通道
     * @return
     */
    @Input(AircraftChannel.TOPIC)
    SubscribableChannel input();     /**
     * 定义生产者发送消息的通道
     * @return
     */
    @Output(AircraftChannel.TOPIC)
    MessageChannel output();
}
  • @Input: 使用input注解指定此方法来处理消息的接收
  • @Output:使用output注解指定此方法来处理消息的发送
  • 一个频道中可以定义多个input和output

定义消息生产者


import com.nghsmart.nghaircraft.channel.AircraftChannel;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.messaging.support.MessageBuilder; @AllArgsConstructor
@Slf4j
@EnableBinding(AircraftChannel.class)
public class AircraftProducer {     private final AircraftChannel aircraftChannel;     public void sendMessage(String message) {
        boolean send = aircraftChannel.output().send(MessageBuilder.withPayload(message).build());
        log.info("send message: {}", message);
    }
}
  • EnableBinding:此注解修饰的类会被Spring容器管理起来,其导入了@Configuration注解。
  • EnableBinding 注解为 AircraftChannel.class 中的接口创建实现类,并通过Spring的自动配置,实现类会对接kafka的adapter,这样就实现了通道和kafkaServer的绑定
  • send:通过注入频道并调用频道中output处理器的send方法将消息发送到kafakServer中的特定topic,即AircraftChannel.TOPIC

定义消息消费者


import com.nghsmart.nghaircraft.channel.AircraftChannel;
import com.nghsmart.nghaircraft.config.RedisTemplateGeneric;
import com.nghsmart.nghaircraft.constant.RedisKeyEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.messaging.Message; @Slf4j
@AllArgsConstructor
@EnableBinding(AircraftChannel.class)
public class AircraftConsumer {     @StreamListener(AircraftChannel.TOPIC)
    public void receiveMessage(Message<String> message) {
        try {
            log.debug("AircraftConsumer_Received_message: {}", message.getPayload());
            //TODO 解析数据
       
        } catch (Exception e) {
            log.error("AircraftConsumer_error,msg={}", e.getMessage());
            e.printStackTrace();
        }
    }
}
  • EnableBinding:此注解修饰的类会被Spring容器管理起来,其导入了@Configuration注解。
  • EnableBinding 注解为 AircraftChannel.class 中的接口创建实现类,并通过Spring的自动配置,实现类会对接kafka的adapter,这样就实现了通道和kafkaServer的绑定
  • StreamListener:通过StreamListener注解为AircraftChannel.TOPIC这个topic创建监听,当kafkaAdapter接收到消息后,将触发回调,调用receiveMessage方法处理消息。

定义Http接口

通过请求接口,发送消息到 kafka



import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; @Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/test")
public class TestController {     private final AircraftProducer aircraftProducer;     @GetMapping("/test1")
    public String test1() {
        aircraftProducer.sendMessage("test1");
        return "test1";
    }
}
  • 新建一个RESTFful接口用于测试消息的发送
  • 通过注入AircraftProducer,调用其sendMessage 方法发送消息
  • 消息发送出去之后,会被AircraftConsumer监听到,并回调到receiveMessage,可以通过观察log,查看消息的整个生命周期流转。

总结

本文介绍了 SpringCloudStream 这个框架的作用和相关生态,并编写了相应的代码示例作为 最佳实践 参考,代码示例会上传到我的代码仓库 SpringBoot漫谈 中(见引用),欢迎大家浏览、学习、交流。

公众号: TechnologyRamble,欢迎大家关注!!!

引用

SpringCloudStream极简教程的更多相关文章

  1. Typora极简教程

    Typora极简教程 ” Markdown 是一种轻量级标记语言,创始人是约翰·格鲁伯(John Gruber).它允许人们 “使用易读易写的纯文本格式编写文档,然后转换成有效的 HTML 文档.” ...

  2. CentOS安装使用.netcore极简教程(免费提供学习服务器)

    本文目标是指引从未使用过Linux的.Neter,如何在CentOS7上安装.Net Core环境,以及部署.Net Core应用. 仅针对CentOS,其它Linux系统类似,命令环节稍加调整: 需 ...

  3. Asky极简教程:零基础1小时学编程,已更新前8节

    Asky极简架构 开源Asky极简架构.超轻量级.高并发.水平扩展.微服务架构 <Asky极简教程:零基础1小时学编程>开源教程 零基础入门,从零开始全程演示,如何开发一个大型互联网系统, ...

  4. Python 极简教程(八)字符串 str

    由于字符串过于重要,请认真看完并保证所有代码都至少敲过一遍. 对于字符串,前面在数据类型中已经提到过.但是由于字符串类型太过于常用,Python 中提供了非常多的关于字符串的操作.而我们在实际编码过程 ...

  5. Nginx 极简教程(快速入门)

    作者:dunwu github.com/dunwu/nginx-tutorial 推荐阅读(点击即可跳转阅读) 1. SpringBoot内容聚合 2. 面试题内容聚合 3. 设计模式内容聚合 4.  ...

  6. 【转】Typora极简教程

    Typora极简教程 Typora download ” Markdown 是一种轻量级标记语言,创始人是约翰·格鲁伯(John Gruber).它允许人们 “使用易读易写的纯文本格式编写文档,然后转 ...

  7. nginx极简教程

    Nginx 极简教程 本项目是一个 Nginx 极简教程,目的在于帮助新手快速入门 Nginx. examples 目录中的示例模拟了工作中的一些常用实战场景,并且都可以通过脚本一键式启动,让您可以快 ...

  8. NodeJS 极简教程 <1> NodeJS 特点 & 使用场景

    NodeJS 极简教程 <1> NodeJS 特点 & 使用场景 田浩 因为看开了所以才去较劲儿.   1. NodeJS是什么 1.1 Node.js is a JavaScri ...

  9. 自制 os 极简教程1:写一个操作系统有多难

    为什么叫极简教程呢?听我慢慢说 不知道正在阅读本文的你,是否是因为想自己动手写一个操作系统.我觉得可能每个程序员都有个操作系统梦,或许是想亲自动手写出来一个,或许是想彻底吃透操作系统的知识.不论是为了 ...

  10. python极简教程04:进程和线程

    测试奇谭,BUG不见. 大家好,我是谭叔. 这一场,主讲python的进程和线程. 目的:掌握初学必须的进程和线程知识. 进程和线程的区别和联系 终于开始加深难度,来到进程和线程的知识点~ 单就这两个 ...

随机推荐

  1. EF Core – QueryFilter & Interception

    主要参考 Global Query Filters Interceptors QueryFilter QueryFilter 就是默认过滤, 非常适合用来做 Soft Delete builder.H ...

  2. 音视频入门-4-ffmpeg命令快速体验音视频开发/ ffmpeg编译过程经历的99八十一难

    <1>我的实验所使用的视频文件告知读者 1. 这是我在ubuntu环境上实验使用的视频文件, 我在windows上查看了详细信息,然后拖进ubuntu内,重命名为video-test.mp ...

  3. /sys/kernel/debug/binder/目录下主要节点含义

    /sys/kernel/debug/binder/目录下主要节点含义 state 显示binder设备的整体状态信息 包括进程数量.线程数量.待处理事务数量等 stats 展示binder操作的统计信 ...

  4. 安装seaborn

    第一步:安装scipy,因为seaborn依赖scipy,如何安装scipy我之前有说过,可以看我之前安装sklearn库的过程中有安装scipy的方法. 第二步:pip install seabor ...

  5. 墨天轮访谈 | SelectDB 衣国垒:Apache Doris(incubating)1.0版本特性解析与未来规划

    分享嘉宾:衣国垒 Apache Doris Committer.SelectDB 联合创始人&CTO 整理:墨天轮社区 导读 大家好,我是来自Apache Doris社区的衣国垒,也是Sele ...

  6. C# Webapi Filter 过滤器 - 生命周期钩子函数 - Action Filter 基础

    ACTION Filter IAsyncACtionFilter 接口 : 1.注入ActionFilter // 注册过滤器 builder.Services.Configure<MvcOpt ...

  7. 011 Python 的打印(花式变色打印)和注释(为什么加个#号就能注释)

    #!/usr/bin/env python # -*- coding:utf-8 -*- # Datatime:2022/7/18 21:29 # Filename:011 Python 的打印和注释 ...

  8. 深入浅出 Kubernetes 项目网关与应用路由

    KubeSphere 项目网关与应用路由提供了一种聚合服务的方式,将集群的内部服务通过一个外部可访问的 IP 地址以 HTTP 或 HTTPs 暴露给集群外部.应用路由定义了这些服务的访问规则,用户可 ...

  9. "开源"是什么?为啥这么火?一定免费吗?

    ​ 在科技快速发展的今天,"开源"一词频频出现在我们的视野中.究竟什么是开源?为何它能在技术圈引发如此热潮? 开源软件到底有什么魅力?它是如何改变软件开发和使用的方式的?开源软件是 ...

  10. DNS域名服务及常用国内DNS服务器地址

    DNS域名服务 DNS服务器分类 缓存域名服务器 也称为高速缓存服务器 通过向其他域名服务器查询获得域名 -> IP 地址记录 将域名查询结果缓存到本地,提高重复查询时的速度 主域名服务器 特定 ...