Spring Cloud Stream消息总线
Springcloud 里面对于MQ的整合一个是前一篇的消息总线一个是本文介绍的消息驱动
大体要学习这么几个知识点:
课题:SpringCloud消息驱动Stream
1.什么是SpringCloud消息驱动
2.消息驱动Stream实现原理
3.消息驱动Stream与传统MQ区别
4.基于消息驱动整合Kafka
5.基于消息驱动整合Rabbitmq
6.基于消息驱动Stream消息分组
什么是消息驱动?
SpringCloud Stream消息驱动可以简化开发人员对消息中间件的使用复杂度,让系统开发人员更多尽力专注与核心业务逻辑的开发。SpringCloud Stream基于SpringBoot实现,自动配置化的功能可以帮助我们快速上手学习,类似与我们之前学习的orm框架,可以平滑的切换多种不同的数据库。
目前SpringCloud Stream 目前只支持 RabbitMQ和kafka
在topic模式上 区别很大的 这两个MQ SpringCloud去整合了 类似于Hibernate 通过对象得到sql语句
开发人员不需要知道具体的MQ底层实现,只需要关心业务逻辑编码就OK了
底层是如何实现的? Stream组件对rabbitMQ和kafka进行封装成同一个API,开发人员只需要对接Stream即可 !
消息驱动原理
绑定器
通过定义绑定器作为中间层,实现了应用程序与消息中间件细节之间的隔离。通过向应用程序暴露统一的Channel通过,是的应用程序不需要再考虑各种不同的消息中间件的实现。当需要升级消息中间件,或者是更换其他消息中间件产品时,我们需要做的就是更换对应的Binder绑定器而不需要修改任何应用逻辑 。
在该模型图上有如下几个核心概念:
- Source: 当需要发送消息时,我们就需要通过Source,Source将会把我们所要发送的消息(POJO对象)进行序列化(默认转换成JSON格式字符串),然后将这些数据发送到Channel中;
- Sink: 当我们需要监听消息时就需要通过Sink来,Sink负责从消息通道中获取消息,并将消息反序列化成消息对象(POJO对象),然后交给具体的消息监听处理进行业务处理;
- Channel: 消息通道是Stream的抽象之一。通常我们向消息中间件发送消息或者监听消息时需要指定主题(Topic)/消息队列名称,但这样一旦我们需要变更主题名称的时候需要修改消息发送或者消息监听的代码,但是通过Channel抽象,我们的业务代码只需要对Channel就可以了,具体这个Channel对应的是那个主题,就可以在配置文件中来指定,这样当主题变更的时候我们就不用对代码做任何修改,从而实现了与具体消息中间件的解耦;
- Binder: Stream中另外一个抽象层。通过不同的Binder可以实现与不同消息中间件的整合,比如上面的示例我们所使用的就是针对Kafka的Binder,通过Binder提供统一的消息收发接口,从而使得我们可以根据实际需要部署不同的消息中间件,或者根据实际生产中所部署的消息中间件来调整我们的配置。
消息驱动有通道,绑定MQ。
生产者消息传递到通道里面之后,通道是跟MQ做绑定,封装的。消息一旦到MQ之后,发送给消费者通道,然后消费者进行消费 。绑定部分是底层帮助实现的。
封装也只是实现了部分功能。MQ的功能不是百分百都实现了的
消息驱动环境搭建
生产者:
maven的pom:
引入配置文件pom:
其实就是对springboot整合rabbitmq再进行了一层封装
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.toov5</groupId>
<artifactId>SpringCloud-stream-producer</artifactId>
<version>0.0.1-SNAPSHOT</version> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<dependencies>
<!-- SpringBoot整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
</dependencies> </project>
然后编码:
在rebbitmq中需要有交换机 队列 底层都帮助实现了! 以通道名称创建交换机 消费者启动时候 随机创建一个队列名称
创建通道:
package com.toov5.stream;
//创建发送通道 import org.springframework.cloud.stream.annotation.Output;
import org.springframework.messaging.SubscribableChannel; public interface SendMsgInterface { //创建发送通道
@Output("my_stream_channel")
SubscribableChannel sendMsg(); }
controller:
package com.toov5.controller; import java.util.UUID; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder; import com.toov5.stream.SendMsgInterface; public class SendMsgController {
//生产者流程
// 1 生产者发送消息通道 获取通道
@Autowired
private SendMsgInterface sendMsgInterface; //2. 生产者投递消息 往通道发送消息
public String sendMsg() {
String msg = UUID.randomUUID().toString();
System.out.println("生产者发送内容msg:" + msg);
Message build = MessageBuilder.withPayload(msg.getBytes()).build();
sendMsgInterface.sendMsg().send(build);
return "success"; }
//3. 开启绑定 然后业务逻辑中就可以从Springboot中拿对象了 启动类去绑定 }
启动类: 开启通道绑定
package com.toov5; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.stream.annotation.EnableBinding; import com.toov5.stream.SendMsgInterface; @SpringBootApplication
@EnableBinding(SendMsgInterface.class) //开启绑定通道(通道接口) 然后业务逻辑中就可以从Springboot中拿对象了
public class AppProducer {
public static void main(String[] args) {
SpringApplication.run(AppProducer.class, args);
}
}
yml:
server:
port: 9000
spring:
application:
name: spingcloud-stream-producer
rabbitmq:
####连接地址
host: 192.168.91.6
####端口号
port: 5672
####账号
username: admin
####密码
password: admin
### 地址 主机独立的virtualhost
virtual-host: /admin_toov5
启动生产者:
此时还没有创建队列 没有进行绑定:
小结:只需要发送信息到通道里面就OK了
下面创建消费者: 对应生产者去写就OK了
maven依赖:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.toov5</groupId>
<artifactId>SpringCloud-stream-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<dependencies>
<!-- SpringBoot整合Web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
</dependencies> </project>
通道接口:
package com.toov5.stream;
//创建发送通道 import org.springframework.cloud.stream.annotation.Input;
import org.springframework.messaging.SubscribableChannel; public interface ReadMsgInterface { //创建发送通道
@Input("my_stream_channel")
SubscribableChannel readMsg(); }
消费者:监听通道
package com.toov5.consumer; import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.stereotype.Component; @Component
public class Consumer { @StreamListener("my_stream_channel") //监听生产者响应的通道
public void readMsg(String msg) {
System.out.println("消费者获取到生产者投递的消息:"+msg);
}
}
启动类: 绑定通道
package com.toov5; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.stream.annotation.EnableBinding; import com.toov5.stream.ReadMsgInterface; @SpringBootApplication
@EnableBinding(ReadMsgInterface.class)
public class AppConsumer {
public static void main(String[] args) {
SpringApplication.run(AppConsumer.class, args);
}
}
yml:
server:
port: 8000
spring:
application:
name: spingcloud-stream-consumer
rabbitmq:
####连接地址
host: 192.168.91.6
####端口号
port: 5672
####账号
username: admin
####密码
password: admin
### 地址 主机独立的virtualhost
virtual-host: /admin_toov5
消费者是有队列的 我们在代码中没有写队列的相关哦 底层会创建的哦 底层自动创建一个队列 绑定交换机 队列名字是随机的
消费者启动后的多了个队列
也绑定上了
下面访问接口 发送个消息试试:
如果换成kafka,修改下maven依赖,配置文件依赖名称改成kafka就OK了~~kafka 的连接信息一配置就搞定
关于消息分组:
生产者投递消息 投递消息到通道后 两个消费者会都进行消费 重复消费了
通过分组去解决,同一个组的消费者会进行轮训消费,只有一个消费者进行消费
consumer关闭,控制台中的队列会消失了。连接关闭会消失,因为木有固定队列哦 随机生成的
我们启动两个队列 通过端口号去标识:
并且绑定了同一个交换机:
访问接口后:
都能收到消息呀
分组配置:
消费者yml加入配置:
cloud:
stream:
bindings:
my_stream_channel: ###指定 管道名称!!!!
#指定该应用实例属于 stream 消费组
group: stream
此时的yml:
server:
port: 8002
spring:
application:
name: spingcloud-stream-consumer
rabbitmq:
####连接地址
host: 192.168.91.6
####端口号
port: 5672
####账号
username: admin
####密码
password: admin
### 地址 主机独立的virtualhost
virtual-host: /admin_toov5
cloud:
stream:
bindings:
my_stream_channel: ###指定 管道名称!!!!
#指定该应用实例属于 stream 消费组
group: stream
启动两个consumer:
分组之后只有一个队列!
绑定信息依然不变
访问:
只有一个能接收消息 且轮训
分组 的概念是由于这个框架搞的 不是原先的MQ固有的
Kafka的策略整合 暂时先不写了 很简单的 有空再补上吧~~~
Spring Cloud Stream消息总线的更多相关文章
- 跟我学SpringCloud | 第八篇:Spring Cloud Bus 消息总线
SpringCloud系列教程 | 第八篇:Spring Cloud Bus 消息总线 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如无特 ...
- spring cloud 2.x版本 Spring Cloud Stream消息驱动组件基础教程(kafaka篇)
本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 本文基于前两篇文章eureka-server.eureka-client.eureka-ri ...
- Spring Cloud(十一)高可用的分布式配置中心 Spring Cloud Bus 消息总线集成(RabbitMQ)
详见:https://www.w3cschool.cn/spring_cloud/spring_cloud-jl8a2ixp.html 上一篇文章,留了一个悬念,Config Client 实现配置的 ...
- spring cloud bus 消息总线 动态刷新配置文件 【actuator 与 RabbitMQ配合完成】
1.前言 单机刷新配置文件,使用actuator就足够了 ,但是 分布式微服务 不可能是单机 ,将会有很多很多的工程 ,无法手动一个一个的发送刷新请求, 因此引入了消息中间件 ,常用的 消息中间件 是 ...
- 干货|Spring Cloud Bus 消息总线介绍
继上一篇 干货|Spring Cloud Stream 体系及原理介绍 之后,本期我们来了解下 Spring Cloud 体系中的另外一个组件 Spring Cloud Bus (建议先熟悉 Spri ...
- Spring Cloud Stream消息驱动之RocketMQ入门(一)
SpringCloudStream目前支持的中间件有RabbitMQ.Kafka,还有我最近在学习的RocketMQ,以下是我学习的笔记 学习Spring cloud Stream 可以先学习一下了解 ...
- Spring Cloud Stream消息驱动@SendTo和消息降级
参考程序员DD大佬的文章,自己新建demo学习学习,由于需要消息回执,看到了@SendTo这个注解能够实现,下面开始学习demo,新建两个项目cloud-stream-consumer消费端 和 cl ...
- Spring Cloud 2-Bus 消息总线(九)
Spring Cloud Bus 1.服务端配置 pom.xml application.yml 2.客户端配置 pom.xml application.yml Controller.java 3 ...
- Spring Cloud Bus 消息总线 RabbitMQ
Spring Cloud Bus将分布式系统中各节点通过轻量级消息代理连接起来. 从而实现例如广播状态改变(例如配置改变)或其他的管理指令. 目前唯一的实现是使用AMQP代理作为传输对象. Sprin ...
随机推荐
- ABAP小白的成长日记--------helloblog
在外企公司培训了3个月,系统的学习了ABAP,希望开通Blog以后和大家一起深入学习交流.印度人的办事效率是出奇的低,赶超国企公务员.虽然内容cover到了几乎所有R/4的内容,但是还有很多知识没有真 ...
- J - 迷宫问题(BFS)
J - 迷宫问题 Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Descriptio ...
- 网络摄像机进行互联网视频直播录像方案的选择,EasyNVS or EasyCloud or EasyGBS?
背景需求 互联网视频直播越来越成为当前大势:直播的需求往往都伴随在录像的需求,对于录像,不同的场景又有不同的方案选择: 本篇博客将会介绍对应的几种录像方案,可以帮助有互联网录像需求的用户进行对应的录像 ...
- 阻塞队列 ArrayBlockingQueue 我给自己挖了一个坑
说一句MMB, 一下午时间, package cn.tbnb1.seckil.quene; import java.util.concurrent.ArrayBlockingQueue; import ...
- Js计算时间差(天、小时、分钟、秒)
<script type="text/javascript"> var date1= '2015/05/01 00:00:00'; //开始时间 var date2 = ...
- access 如何导出 cvs 文件?
三部曲 1 access 数据表导出 excel 表格 2 excel 另存为 *.cvs 格式文件 3 数据库导入 *.cvs 文件
- (2)linux未使用eth0,未使用IPV4导致无法连接
首先ifconfig查看网络IP 看,我这里默认启用了2个网卡,一个是eth0,另一个是lo(基于loopback方式) 1.如果有eth0则做:界面修改 (1)输入命令setup,选择network ...
- PopuWindow和软件盘共存时的设置
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/mingyue_1128/article/details/32316069 一.键盘不消失,popuw ...
- 《Deep learning》第四章——数值计算
数值计算 机器学习算法通常需要大量的数值计算.这通常是指通过迭代过程更新解的估计值来解决数学问题的算法,而不是通过解析过程推导出公式来提供正确解的方法.常见的操作包括优化(找到最小化或最大化函数值的参 ...
- IIS 6.0上部署.NET 4.0网站
最近需要把VS2010开发的网站部署到Windows Server 2003的服务器上去, Windows Server 2003操作系统自带的为IIS 6.0,IIS 6.0一般只支持.NET 2. ...