案例代码:https://github.com/q279583842q/springcloud-e-book

  在实际开发过程中,服务与服务之间通信经常会使用到消息中间件,而以往使用了哪个中间件比如RabbitMQ,那么该中间件和系统的耦合性就会非常高,如果我们要替换为Kafka那么变动会比较大,这时我们可以使用SpringCloudStream来整合我们的消息中间件,来降低系统和中间件的耦合性。

一、什么是SpringCloudStream

  官方定义 Spring Cloud Stream 是一个构建消息驱动微服务的框架。

  应用程序通过 inputs 或者 outputs 来与 Spring Cloud Stream 中binder 交互,通过我们配置来 binding ,而 Spring Cloud Stream 的 binder 负责与消息中间件交互。所以,我们只需要搞清楚如何与 Spring Cloud Stream 交互就可以方便使用消息驱动的方式。

  通过使用Spring Integration来连接消息代理中间件以实现消息事件驱动。Spring Cloud Stream 为一些供应商的消息中间件产品提供了个性化的自动化配置实现,引用了发布-订阅、消费组、分区的三个核心概念。目前仅支持RabbitMQKafka

二、Stream 解决了什么问题?

  Stream解决了开发人员无感知的使用消息中间件的问题,因为Stream对消息中间件的进一步封装,可以做到代码层面对中间件的无感知,甚至于动态的切换中间件(rabbitmq切换为kafka),使得微服务开发的高度解耦,服务可以关注更多自己的业务流程

官网结构图

组成 说明
Middleware 中间件,目前只支持RabbitMQ和Kafka
Binder Binder是应用与消息中间件之间的封装,目前实行了Kafka和RabbitMQ的Binder,通过Binder可以很方便的连接中间件,可以动态的改变消息类型(对应于Kafka的topic,RabbitMQ的exchange),这些都可以通过配置文件来实现
@Input 注解标识输入通道,通过该输入通道接收到的消息进入应用程序
@Output 注解标识输出通道,发布的消息将通过该通道离开应用程序
@StreamListener 监听队列,用于消费者的队列的消息接收
@EnableBinding 指信道channel和exchange绑定在一起

三、消息驱动入门案例

  我们通过一个入门案例来演示下通过stream来整合RabbitMQ来实现消息的异步通信的效果,所以首先要开启RabbitMQ服务,RabbitMQ不清楚的请参考此文:https://dpb-bobokaoya-sm.blog.csdn.net/article/details/90409404

1.创建消息发送者服务

1.1 创建项目

  创建一个SpringCloud项目

1.2 pom文件

  pom文件中重点是要添加spring-cloud-starter-stream-rabbit这个依赖

<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.13.RELEASE</version>
</parent>
<groupId>com.bobo</groupId>
<artifactId>stream-sender</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

1.3 配置文件

  配置文件中除了必要的服务名称端口Eureka的信息外我们还要添加RabbitMQ的注册信息

spring.application.name=stream-sender
server.port=9060
#设置服务注册中心地址,指向另一个注册中心
eureka.client.serviceUrl.defaultZone=http://dpb:123456@eureka1:8761/eureka/,http://dpb:123456@eureka2:8761/eureka/ #rebbitmq 链接信息
spring.rabbitmq.host=192.168.88.150
spring.rabbitmq.port=5672
spring.rabbitmq.username=dpb
spring.rabbitmq.password=123
spring.rabbitmq.virtualHost=/

1.4 创建消费发送者接口

  创建一个发送消息的接口。具体如下:方法名称自定义,返回类型必须是SubscribableChannel,在Output注解中指定交换器名称。

/**
* 发送消息的接口
* @author dengp
*
*/
public interface ISendeService { /**
* 指定输出的交换器名称
* @return
*/
@Output("dpb-exchange")
SubscribableChannel send();
}

1.5 启动类

  在启动类中通过@EnableBinding注解绑定我们创建的接口类。

@SpringBootApplication
@EnableEurekaClient
// 绑定我们刚刚创建的发送消息的接口类型
@EnableBinding(value={ISendeService.class})
public class StreamSenderStart { public static void main(String[] args) {
SpringApplication.run(StreamSenderStart.class, args);
}
}

2.创建消息消费者服务

2.1 创建项目

2.2 pom文件

  添加的依赖和发送消息的服务是一致的

<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.13.RELEASE</version>
</parent>
<groupId>com.bobo</groupId>
<artifactId>stream-receiver</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

2.3 配置文件

  注意修改服务名称和端口

spring.application.name=stream-receiver
server.port=9061
#设置服务注册中心地址,指向另一个注册中心
eureka.client.serviceUrl.defaultZone=http://dpb:123456@eureka1:8761/eureka/,http://dpb:123456@eureka2:8761/eureka/ #rebbitmq 链接信息
spring.rabbitmq.host=192.168.88.150
spring.rabbitmq.port=5672
spring.rabbitmq.username=dpb
spring.rabbitmq.password=123
spring.rabbitmq.virtualHost=/

2.4 创建接收消息的接口

  此接口和发送消息的接口相似,注意使用的是@Input注解。

/**
* 接收消息的接口
* @author dengp
*
*/
public interface IReceiverService { /**
* 指定接收的交换器名称
* @return
*/
@Input("dpb-exchange")
SubscribableChannel receiver();
}

2.5 创建处理消息的处理类

  注意此类并不是实现上面创建的接口。而是通过@EnableBinding来绑定我们创建的接口,同时通过@StreamListener注解来监听dpb-exchange对应的消息服务

/**
* 具体接收消息的处理类
* @author dengp
*
*/
@Service
@EnableBinding(IReceiverService.class)
public class ReceiverService { @StreamListener("dpb-exchange")
public void onReceiver(byte[] msg){
System.out.println("消费者:"+new String(msg));
}
}

2.6 启动类

  同样要添加@EnableBinding注解

@SpringBootApplication
@EnableEurekaClient
@EnableBinding(value={IReceiverService.class})
public class StreamReceiverStart { public static void main(String[] args) {
SpringApplication.run(StreamReceiverStart.class, args);
}
}

3.编写测试代码

  通过单元测试来测试服务。

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.test.context.junit4.SpringRunner; import com.bobo.stream.StreamSenderStart;
import com.bobo.stream.sender.ISendeService; @RunWith(SpringRunner.class)
@SpringBootTest(classes=StreamSenderStart.class)
public class StreamTest { @Autowired
private ISendeService sendService; @Test
public void testStream(){
String msg = "hello stream ...";
// 将需要发送的消息封装为Message对象
Message message = MessageBuilder
.withPayload(msg.getBytes())
.build();
sendService.send().send(message );
}
}

启动消息消费者后,执行测试代码。结果如下:

消息接收者获取到了发送者发送的消息,同时我们在RabbitMQ的web界面也可以看到相关的信息

总结

  我们同stream实现了消息中间件的使用,我们发现只有在两处地址和RabbitMQ有耦合,第一处是pom文件中的依赖,第二处是application.properties中的RabbitMQ的配置信息,而在具体的业务处理中并没有出现任何RabbitMQ相关的代码,这时如果我们要替换为Kafka的话我们只需要将这两处换掉即可,即实现了中间件和服务的高度解耦。

Spring cloud stream【入门介绍】的更多相关文章

  1. Spring Cloud Stream介绍-Spring Cloud学习第八天(非原创)

    文章大纲 一.什么是Spring Cloud Stream二.Spring Cloud Stream使用介绍三.Spring Cloud Stream使用细节四.参考文章 一.什么是Spring Cl ...

  2. Spring Cloud 系列之 Spring Cloud Stream

    Spring Cloud Stream 是消息中间件组件,它集成了 kafka 和 rabbitmq .本篇文章以 Rabbit MQ 为消息中间件系统为基础,介绍 Spring Cloud Stre ...

  3. 官方文档中文版!Spring Cloud Stream 快速入门

    本文内容翻译自官方文档,spring-cloud-stream docs,对 Spring Cloud Stream的应用入门介绍. 一.Spring Cloud Stream 简介 官方定义 Spr ...

  4. Spring Cloud Stream学习(五)入门

    前言: ​ 在了解完RabbitMQ后,再来学习SpringCloudStream就轻松很多了,SpringCloudStream现在主要支持两种消息中间件,一个是RabbitMQ,还有一个是KafK ...

  5. Spring Cloud Stream教程(一)介绍Spring Cloud Stream

    Spring Cloud Stream是构建消息驱动的微服务应用程序的框架.Spring Cloud Stream基于Spring Boot建立独立的生产级Spring应用程序,并使用Spring I ...

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

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

  7. Spring Cloud Stream消费失败后的处理策略(四):重新入队(RabbitMQ)

    应用场景 之前我们已经通过<Spring Cloud Stream消费失败后的处理策略(一):自动重试>一文介绍了Spring Cloud Stream默认的消息重试功能.本文将介绍Rab ...

  8. Spring Cloud Stream消费失败后的处理策略(三):使用DLQ队列(RabbitMQ)

    应用场景 前两天我们已经介绍了两种Spring Cloud Stream对消息失败的处理策略: 自动重试:对于一些因环境原因(如:网络抖动等不稳定因素)引发的问题可以起到比较好的作用,提高消息处理的成 ...

  9. Spring Cloud Stream消费失败后的处理策略(二):自定义错误处理逻辑

    应用场景 上一篇<Spring Cloud Stream消费失败后的处理策略(一):自动重试>介绍了默认就会生效的消息重试功能.对于一些因环境原因.网络抖动等不稳定因素引发的问题可以起到比 ...

随机推荐

  1. 【转】ARRAYLIST VECTOR LINKEDLIST 区别与用法

    转自:http://www.cnblogs.com/mgod/archive/2007/08/05/844011.html ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实 ...

  2. 从JDBC到commons-dbutils

    1.前言 玩过Java web的人应该都接触过JDBC,正是有了它,Java程序才能轻松地访问数据库.JDBC很多人都会,但是为什么我还要写它呢?我曾经一度用烂了JDBC,一度认为JDBC不过如此,后 ...

  3. The bundle does not contain an app icon for iPhone / iPod Touch of exactly &#39;120x120&#39; pixels, in .pn

    xcode 6.3 载发生时的应用'Missing recommended icon file - The bundle does not contain an app icon for iPhone ...

  4. VCL to UniGUI Migration Wizard

    Free Evaluation Edition of The Automatic Migration Scripting Wizard For Converting Legacy Delphi Cod ...

  5. Get and Post(Unity3D六个发展)

    猴子原创,欢迎转载. 转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=565 unity3d中的www ...

  6. WPF在3D Cad模型中利用TextureCoordinates实现颜色渐变显示偏差值的变化

    原文:WPF在3D Cad模型中利用TextureCoordinates实现颜色渐变显示偏差值的变化 注:最近在做3D机械模型重建方面的软件,需要根据光栅传感器采集的数据绘制3D图形,并显示出色差以及 ...

  7. abp框架(aspnetboilerplate)设置前端报错显示

    abp在后端抛出异常 throw new UserFriendlyException($"抛出一个错误"); 在发布之前,需要设置是否把报错发送给前端 如果将此设置为true,则会 ...

  8. WPF中Style文件的引用——使用xaml代码或者C#代码动态加载

    原文:WPF中Style文件的引用--使用xaml代码或者C#代码动态加载 WPF中控件拥有很多依赖属性(Dependency Property),我们可以通过编写自定义Style文件来控制控件的外观 ...

  9. Emgu-WPF 激光雷达研究-移动物体检测

    原文:Emgu-WPF 激光雷达研究-移动物体检测 接上篇: https://blog.csdn.net/u013224722/article/details/80738619 先pose出效果图,下 ...

  10. 用户控件(UserControl)

    简介 "用户控件"继承自UserControl,而UserControl继承自ContentControl,也就是内容控件UserControl和Window是一个层次上的,都有x ...