什么是消息驱动?

SpringCloud Stream消息驱动可以简化开发人员对消息中间件的使用复杂度,让系统开发人员更多尽力专注与核心业务逻辑的开发。SpringCloud Stream基于SpringBoot实现,自动配置化的功能可以帮助我们快速上手学习,类似与我们之前学习的orm框架,可以平滑的切换多种不同的数据库。

目前SpringCloud Stream 目前只支持 rabbitMQ和kafka

消息驱动原理

绑定器

通过定义绑定器作为中间层,实现了应用程序与消息中间件细节之间的隔离。通过向应用程序暴露统一的Channel通过,是的应用程序不需要再考虑各种不同的消息中间件的实现。当需要升级消息中间件,或者是更换其他消息中间件产品时,我们需要做的就是更换对应的Binder绑定器而不需要修改任何应用逻辑 。

在该模型图上有如下几个核心概念:

  • Source: 当需要发送消息时,我们就需要通过Source,Source将会把我们所要发送的消息(POJO对象)进行序列化(默认转换成JSON格式字符串),然后将这些数据发送到Channel中;
  • Sink: 当我们需要监听消息时就需要通过Sink来,Sink负责从消息通道中获取消息,并将消息反序列化成消息对象(POJO对象),然后交给具体的消息监听处理进行业务处理;
  • Channel: 消息通道是Stream的抽象之一。通常我们向消息中间件发送消息或者监听消息时需要指定主题(Topic)/消息队列名称,但这样一旦我们需要变更主题名称的时候需要修改消息发送或者消息监听的代码,但是通过Channel抽象,我们的业务代码只需要对Channel就可以了,具体这个Channel对应的是那个主题,就可以在配置文件中来指定,这样当主题变更的时候我们就不用对代码做任何修改,从而实现了与具体消息中间件的解耦;
  • Binder: Stream中另外一个抽象层。通过不同的Binder可以实现与不同消息中间件的整合,比如上面的示例我们所使用的就是针对Kafka的Binder,通过Binder提供统一的消息收发接口,从而使得我们可以根据实际需要部署不同的消息中间件,或者根据实际生产中所部署的消息中间件来调整我们的配置。

消息驱动环境搭建

生产者环境

Maven依赖信息

  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>2.0.1.RELEASE</version>
  5. </parent>
  6. <dependencies>
  7. <!-- SpringBoot整合Web组件 -->
  8. <dependency>
  9. <groupId>org.springframework.boot</groupId>
  10. <artifactId>spring-boot-starter-web</artifactId>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework.cloud</groupId>
  14. <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
  15. <version>2.0.1.RELEASE</version>
  16. </dependency>
  17. </dependencies>

application.yml信息

  1. server:
  2. port: 9000
  3. spring:
  4. application:
  5. name: spingcloud-stream-producer
  6. # rabbitmq:
  7. # host: 192.168.174.128
  8. # port: 5672
  9. # username: guest
  10. # password: guest

创建管道

  1. // 创建管道接口
  2. public interface SendMessageInterface {
  3.  
  4. // 创建一个输出管道,用于发送消息
  5. @Output("my_msg")
  6. SubscribableChannel sendMsg();
  7.  
  8. }

发送消息

  1. @RestController
  2. public class SendMsgController {
  3. @Autowired
  4. private SendMessageInterface sendMessageInterface;
  5.  
  6. @RequestMapping("/sendMsg")
  7. public String sendMsg() {
  8. String msg = UUID.randomUUID().toString();
  9. System.out.println("生产者发送内容msg:" + msg);
  10. Message build = MessageBuilder.withPayload(msg.getBytes()).build();
  11. sendMessageInterface.sendMsg().send(build);
  12. return "success";
  13. }
  14.  
  15. }

启动服务

  1. @SpringBootApplication
  2. @EnableBinding(SendMessageInterface.class) // 开启绑定
  3. public class AppProducer {
  4.  
  5. public static void main(String[] args) {
  6. SpringApplication.run(AppProducer.class, args);
  7. }
  8.  
  9. }

消费者环境

Maven

  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>2.0.1.RELEASE</version>
  5. </parent>
  6. <dependencies>
  7. <!-- SpringBoot整合Web组件 -->
  8. <dependency>
  9. <groupId>org.springframework.boot</groupId>
  10. <artifactId>spring-boot-starter-web</artifactId>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework.cloud</groupId>
  14. <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
  15. <version>2.0.1.RELEASE</version>
  16. </dependency>
  17. </dependencies>

application.yml

  1. server:
  2. port: 9000
  3. spring:
  4. application:
  5. name: spingcloud-stream-consumer
  6. # rabbitmq:
  7. # host: 192.168.174.128
  8. # port: 5672
  9. # username: guest
  10. # password: guest

管道中绑定消息

  1. public interface RedMsgInterface {
  2.  
  3. // 从管道中获取消息
  4. @Input("my_msg")
  5. SubscribableChannel redMsg();
  6. }

消费者获取消息

  1. @Component
  2. public class Consumer {
  3.  
  4. @StreamListener("my_msg")
  5. public void listener(String msg) {
  6. System.out.println("消费者获取生产消息:" + msg);
  7. }
  8.  
  9. }

启动消费者

  1. @SpringBootApplication
  2. @EnableBinding(RedMsgInterface.class)
  3. public class AppConsumer {
  4.  
  5. public static void main(String[] args) {
  6. SpringApplication.run(AppConsumer.class, args);
  7. }
  8.  
  9. }

消费组

在现实的业务场景中,每一个微服务应用为了实现高可用和负载均衡,都会集群部署,按照上面我们启动了两个应用的实例,消息被重复消费了两次。为解决这个问题,Spring Cloud Stream 中提供了消费组,通过配置 spring.cloud.stream.bindings.myInput.group 属性为应用指定一个组名,下面修改下配置文件,

  1. server:
  2. port: 8001
  3. spring:
  4. application:
  5. name: spring-cloud-stream
  6. # rabbitmq:
  7. # host: 192.168.174.128
  8. # port: 5672
  9. # username: guest
  10. # password: guest
  11. cloud:
  12. stream:
  13. bindings:
  14. mymsg: ###指定 管道名称
  15. #指定该应用实例属于 stream 消费组
  16. group: stream

修改消费者

  1. @Component
  2. public class Consumer {
  3. @Value("${server.port}")
  4. private String serverPort;
  5.  
  6. @StreamListener("my_msg")
  7. public void listener(String msg) {
  8. System.out.println("消费者获取生产消息:" + msg + ",端口号:" + serverPort);
  9. }
  10.  
  11. }

更改环境为kafka

Maven依赖

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-stream-kafka</artifactId>
  4. <version>2.0.1.RELEASE</version>
  5. </dependency>

生产者配置

  1. server:
  2. port: 9000
  3. spring:
  4. cloud:
  5. stream:
  6. # 设置成使用kafka
  7. kafka:
  8. binder:
  9. # Kafka的服务端列表,默认localhost
  10. brokers: 192.168.212.174:9092,192.168.212.175:9092,192.168.212.176:9092
  11. # Kafka服务端连接的ZooKeeper节点列表,默认localhost
  12. zkNodes: 192.168.212.174:2181,192.168.212.175:2181,192.168.212.176:2181
  13. minPartitionCount: 1
  14. autoCreateTopics: true
  15. autoAddPartitions: true

消费者配置

  1. server:
  2. port: 8000
  3. spring:
  4. application:
  5. name: springcloud_kafka_consumer
  6. cloud:
  7. instance-count: 1
  8. instance-index: 0
  9. stream:
  10. kafka:
  11. binder:
  12. brokers: 192.168.212.174:9092,192.168.212.175:9092,192.168.212.176:9092
  13. zk-nodes: 192.168.212.174:2181,192.168.212.175:2181,192.168.212.176:2181
  14. auto-add-partitions: true
  15. auto-create-topics: true
  16. min-partition-count: 1
  17. bindings:
  18. input:
  19. destination: my_msg
  20. group: s1
  21. consumer:
  22. autoCommitOffset: false
  23. concurrency: 1
  24. partitioned: false

《springcloud 五》springcloud stream的更多相关文章

  1. 每天学点SpringCloud(十四):Zipkin使用SpringCloud Stream以及Elasticsearch

    在前面的文章中,我们已经成功的使用Zipkin收集了项目的调用链日志.但是呢,由于我们收集链路信息时采用的是http请求方式收集的,而且链路信息没有进行保存,ZipkinServer一旦重启后就会所有 ...

  2. Rabbitmq基本使用 SpringBoot整合Rabbit SpringCloud Stream+Rabbit

    https://blog.csdn.net/m0_37867405/article/details/80793601 四.docker中使用rabbitmq 1. 搭建和启动 使用地址:rabbitm ...

  3. SpringCloud学习笔记(九、SpringCloud Stream)

    目录: 什么是SpringCloud Stream 如何使用SpringCloud Stream 消息分流 什么是SpringCloud Stream: SpringCloud Stream是一个用于 ...

  4. SpringCloud Stream使用案例

    官方定义 Spring Cloud Stream 是一个构建消息驱动微服务的框架. 应用程序通过 inputs 或者 outputs 来与 Spring Cloud Stream 中binder 交互 ...

  5. SpringCloud Stream 消息驱动

    1.什么是消息驱动 SpringCloud Stream消息驱动可以简化开发人员对消息中间件的使用复杂度,让系统开发人员更多尽力专注与核心业务逻辑的开发.SpringCloud Stream基于Spr ...

  6. SpringCloud系列之SpringCloud Stream

    SpringCloud Stream SpringCloud Config SpringCloud Gatewa SpringCloud Hystrix SpringCloud 第一部分 文章目录 S ...

  7. 九. SpringCloud Stream消息驱动

    1. 消息驱动概述 1.1 是什么 在实际应用中有很多消息中间件,比如现在企业里常用的有ActiveMQ.RabbitMQ.RocketMQ.Kafka等,学习所有这些消息中间件无疑需要大量时间经历成 ...

  8. 使用SpringCloud Stream结合rabbitMQ实现消息消费失败重发机制

    前言:实际项目中经常遇到消息消费失败了,要进行消息的重发.比如支付消息消费失败后,要分不同时间段进行N次的消息重发提醒. 本文模拟场景 当金额少于100时,消息消费成功 当金额大于100,小于200时 ...

  9. SpringCloud Stream

    1.介绍 官网:https://www.springcloud.cc/spring-cloud-dalston.html#_spring_cloud_stream 1.1定义 是一个构建消息驱动微服务 ...

随机推荐

  1. RTSP协议

        1.RTSP与几个相关协议 RTSP(Real Time Streaming Protocol)实时流协议,是用来控制声音或影像的多媒体串流协议,并允许同时多个串流需求控制,传输时所用的网络通 ...

  2. 蓝桥杯训练 2n皇后问题

    给定一个n*n的棋盘,棋盘中有一些位置不能放皇后.现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行.同一列或同一条对角线上,任意的两个白皇后都不在同一行.同一列或同一条对角线上 ...

  3. BZOJ_2957_楼房重建_线段树

    BZOJ_2957_楼房重建_线段树 Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多 ...

  4. 【算法模板】Binary Search 二分查找

    模板:(通用模板,推荐) 给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开始),如果target不存在于数组中,返回-1. ...

  5. 网络最大流dinic模板

    #include<iostream> #include<cstdio> #include<cstring> #include<queue> using ...

  6. Linux命令总结_命令执行顺序

    有时候,我们需要一个命令执行完之后再去执行另一个命令,使用 &&和 ||可以完成 这样的功能,相应的命令可以是系统命令或shell脚本 Shell还提供了在当前shell或子shell ...

  7. Programming With Objective-C---- Introduction ---- Objective-C 学习(一)

    About Objective-C Objective-C is the primary programming language you use when writing software for ...

  8. 26.OpenIdConnect获取用户信息的两种方式

    openId在OAuth基础之上,在下面这红框内拿到Authorization Code之后还可以返回IdToken. IdToken和AccessToken一起返回.IdToken就会包括了用户的信 ...

  9. Deep Learning - Install the Development Environment

    WLS(Windows Subsystem for Linux) Base WLS Installation Guide Initializing a newly installed distro W ...

  10. HTML5学习笔记(一)相关概率

    HTML5的设计目的是为了在移动设备上支持多媒体. 声明:<!DOCTYPE html> 注意:对于中文网页需要使用 <meta charset="utf-8"& ...