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消息总线的更多相关文章

  1. 跟我学SpringCloud | 第八篇:Spring Cloud Bus 消息总线

    SpringCloud系列教程 | 第八篇:Spring Cloud Bus 消息总线 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如无特 ...

  2. spring cloud 2.x版本 Spring Cloud Stream消息驱动组件基础教程(kafaka篇)

    本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 本文基于前两篇文章eureka-server.eureka-client.eureka-ri ...

  3. Spring Cloud(十一)高可用的分布式配置中心 Spring Cloud Bus 消息总线集成(RabbitMQ)

    详见:https://www.w3cschool.cn/spring_cloud/spring_cloud-jl8a2ixp.html 上一篇文章,留了一个悬念,Config Client 实现配置的 ...

  4. spring cloud bus 消息总线 动态刷新配置文件 【actuator 与 RabbitMQ配合完成】

    1.前言 单机刷新配置文件,使用actuator就足够了 ,但是 分布式微服务 不可能是单机 ,将会有很多很多的工程 ,无法手动一个一个的发送刷新请求, 因此引入了消息中间件 ,常用的 消息中间件 是 ...

  5. 干货|Spring Cloud Bus 消息总线介绍

    继上一篇 干货|Spring Cloud Stream 体系及原理介绍 之后,本期我们来了解下 Spring Cloud 体系中的另外一个组件 Spring Cloud Bus (建议先熟悉 Spri ...

  6. Spring Cloud Stream消息驱动之RocketMQ入门(一)

    SpringCloudStream目前支持的中间件有RabbitMQ.Kafka,还有我最近在学习的RocketMQ,以下是我学习的笔记 学习Spring cloud Stream 可以先学习一下了解 ...

  7. Spring Cloud Stream消息驱动@SendTo和消息降级

    参考程序员DD大佬的文章,自己新建demo学习学习,由于需要消息回执,看到了@SendTo这个注解能够实现,下面开始学习demo,新建两个项目cloud-stream-consumer消费端 和 cl ...

  8. Spring Cloud 2-Bus 消息总线(九)

    Spring Cloud  Bus  1.服务端配置 pom.xml application.yml 2.客户端配置 pom.xml application.yml Controller.java 3 ...

  9. Spring Cloud Bus 消息总线 RabbitMQ

    Spring Cloud Bus将分布式系统中各节点通过轻量级消息代理连接起来. 从而实现例如广播状态改变(例如配置改变)或其他的管理指令. 目前唯一的实现是使用AMQP代理作为传输对象. Sprin ...

随机推荐

  1. urllib基本使用 urlopen(),Request

    urllib包含的常用模块:import urllib.request # 打开和读取url请求import urllib.error # 异常处理模块import urllib.parse # ur ...

  2. 使用PHP创建一个socket服务端

    与常规web开发不同,使用socket开发可以摆脱http的限制.可自定义协议,使用长连接.PHP代码常驻内存等.学习资料来源于workerman官方视频与文档. 通常创建一个socket服务包括这几 ...

  3. 集合 Vector ArrayList 集合一

    集合是存储对象的,与对象数组不同,集合可以自动的扩大自己的容量,像StringBuffer一样,存储的对象类型可以不一致,(object数组). 方法: add();remove();get();se ...

  4. Python 使用MySQL

    在导入MySQLdb之前,需要安装MySQLdb模块.使用pip安装,命令如下: pip install MySQL-python 安装成功后,导入MySQLdb模块 import MySQLdb 连 ...

  5. Tarjan 求桥,割,强连通

    最近遇到了这种模板题,记录一下 tarjan求桥,求割 #include <bits/stdc++.h> using namespace std; #define MOD 99824435 ...

  6. jetty 通过配置文件嵌入式启动web服务

    定义 jetty.xml 启动文件 <?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty/ ...

  7. 巨蟒django之权限8:排序&&菜单展开权限归属

    1.权限控制的流程+表结构 内容回顾: wsgi:socket进行收发消息 中间件:(超级重点的面试题)在全局范围内控制django的输入和输出的一个钩子,处理输入和输出说白了就是处理请求和响应req ...

  8. 使用 mock 测试

    参考文章:https://semaphoreci.com/community/tutorials/getting-started-with-mocking-in-python What are the ...

  9. js split 的用法和定义 js split分割字符串成数组的实例代码

    关于js split的用法,我们经常用来将字符串分割为数组方便后续操作,今天写一段广告判断代码的时候,竟然忘了split的用法了,特整理下,方便需要的朋友, 关于js split的用法其它也不多说什么 ...

  10. velocity 的 escape实现

    EscapeHtmlReference的escape方法调用以下方法实现: StringEscapeUtils.escapeHtml(param); 再调用 org.apache.commons.la ...