SpringCloudStream实战
Spring Cloud Stream是一个用于构建消息驱动的微服务应用程序的框架。Spring Cloud Stream构建于Spring Boot之上,用于创建独立的生产级Spring应用程序,并使用Spring Integration提供与消息代理的连接。也就是说,Spring Cloud Stream是构建于Spring Boot和Spring Integration之上的框架,帮助创建事件驱动或消息驱动的微服务。
主要模型如图:
这里我们使用Kafka作为消息底层设施,原因见: 为什么我们从RabbitMQ切换到apache kafka?
引入Kafka的Stream启动器:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
微服务架构遵循“ 智能端点和哑管 ”原则,端点之间的通信由RabbitMQ或Apache Kafka等消息传递中间件方驱动,服务通过这些端点或通道发布领域事件进行通信。
首先我们定义一个接口,定义输入和输出队列管道:
public interface GreetingsStreams {
String INPUT = "greetings-in";
String OUTPUT = "greetings-out";
@Input(INPUT)
SubscribableChannel inboundGreetings();
@Output(OUTPUT)
MessageChannel outboundGreetings();
}
@Input注释用来表示输入的消息队列,通过该通道接收消息并输入当前应用;@Output注释表示一个输出通道,通过它发布消息出去。@Input和@Output注解可以采取指定的通道名称(比如这里greetings-in greetings-out")作为参数,如果未提供名称,则使用注释的方法名称。
在application.yaml或property中具体配置该消息通道到Kafka:
spring:
cloud:
stream:
kafka:
binder:
brokers: localhost:9092
bindings:
greetings-in:
destination: greetings
contentType: application/json
greetings-out:
destination: greetings
contentType: application/json
其中greetings-in和greetings-out配置到Kafka具体的主题topic名称为greetings,序列化类型是json,kafka默认端口在本地9092。
好了,底层基础设施准备完成,现在需要将这个设施安装到我们的应用中。
@EnableBinding(GreetingsStreams.class)
public class StreamsConfig {
}
@EnableBinding将应用配置绑定接口GreetingsStreams中定义的通道INPUT和OUTPUT。
现在我们的应用和消息基础设施已经绑定了,可使用@StreamListener到具体方法以接收具体的流处理事件了。
@Component
@Slf4j
public class GreetingsListener {
@StreamListener(GreetingsStreams.INPUT)
public void handleGreetings(@Payload Greetings greetings) {
log.info("Received greetings: {}", greetings);
}
}
StreamListeners 是消息监听者处理方法,接收类型的传入消息Greetings,可以看到框架的核心功能之一:它尝试自动将传入的消息有效负载转换为类型Person。
上面方法是一个没有返回结果的void方法,如果有返回结果,必须使用@SendTo注释指定方法返回的数据的输出绑定队列目标output,如以下示例所示;通过
@Component
@Slf4j
public class GreetingsListener {
@StreamListener(GreetingsStreams.INPUT)
@SendTo(GreetingsStreams.OUTPUT)
public String handleGreetings(Greetings greetings) {
log.info("Received greetings: {}", greetings);
return "Received greetings: {}" + greetings;
}
}
Spring cloud stream实现了一个默认的Processor类,类似我们的GreetingsStreams接口,也就是说,可以不用自己做这个接口
public interface Processor extends Source, Sink {
}
public interface Source {
String OUTPUT = "output"; @Output("output")
MessageChannel output();
}
public interface Sink {
String INPUT = "input"; @Input("input")
SubscribableChannel input();
}
如果使用默认的Processor通道名称,注意配置文件里也要配置成相应的通道名。
测试运行
有了接收方,下面我们实现一个发送方,我们通过调用rest接口发送消息,先看看发送方代码:
@Service
@Slf4j
public class GreetingsService {
private final GreetingsStreams greetingsStreams; public GreetingsService(GreetingsStreams greetingsStreams) {
this.greetingsStreams = greetingsStreams;
} public void sendGreeting(final Greetings greetings) {
log.info("Sending greetings {}", greetings);
MessageChannel messageChannel = greetingsStreams.outboundGreetings();
messageChannel.send(MessageBuilder
.withPayload(greetings)
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON)
.build());
}
}
我们暴露一个端口来调用这个发送方:
@RestController
public class GreetingsController {
private final GreetingsService greetingsService;
public GreetingsController(GreetingsService greetingsService) {
this.greetingsService = greetingsService;
}
@GetMapping("/greetings")
@ResponseStatus(HttpStatus.ACCEPTED)
public void greetings(@RequestParam("message") String message) {
Greetings greetings = Greetings.builder()
.message(message)
.timestamp(System.currentTimeMillis())
.build();
greetingsService.sendGreeting(greetings);
} }
也就是说:这个发送方REST和发送服务 与我们的GreetingsListener是通过消息系统通讯的,不是直接在发送服务里调用GreetingsListener的方法,这样这两者之间就解耦了。
下面我们用postman调用:
http://localhost:8080/greetings?message=hello
控制台结果输出:
c.e.c.GreetingsService : Sending greetings Greetings(timestamp=1535614400754, message=hello) c.e.c.GreetingsListener : Received greetings: Greetings(timestamp=1535614400754, message=hello)
一个发送和一个接受完成了一个请求调用,如果GreetingsListener还有返回结果,是放在greetings-out之中的,那么GreetingsListener就变成发送方了,我们也可以参考这套做法再做个监听器。
---------------------
原文:https://blog.csdn.net/qq_42950313/article/details/82224660
SpringCloudStream实战的更多相关文章
- RabbitMQ与Spring的框架整合之Spring Cloud Stream实战
1.RabbitMQ与Spring Cloud Stream整合实战.SpringCloud Stream整体结构核心概念图,如下所示: 图示解释:Outputs输出,即消息的发送端.Inputs输入 ...
- springCloud学习5(Spring-Cloud-Stream事件驱动)
springcloud 总集:https://www.tapme.top/blog/detail/2019-02-28-11-33 代码见文章结尾 想想平常生活中做饭的场景,在用电饭锅做饭的同时, ...
- SSH实战 · 唯唯乐购项目(上)
前台需求分析 一:用户模块 注册 前台JS校验 使用AJAX完成对用户名(邮箱)的异步校验 后台Struts2校验 验证码 发送激活邮件 将用户信息存入到数据库 激活 点击激活邮件中的链接完成激活 根 ...
- GitHub实战系列汇总篇
基础: 1.GitHub实战系列~1.环境部署+创建第一个文件 2015-12-9 http://www.cnblogs.com/dunitian/p/5034624.html 2.GitHub实战系 ...
- MySQL 系列(四)主从复制、备份恢复方案生产环境实战
第一篇:MySQL 系列(一) 生产标准线上环境安装配置案例及棘手问题解决 第二篇:MySQL 系列(二) 你不知道的数据库操作 第三篇:MySQL 系列(三)你不知道的 视图.触发器.存储过程.函数 ...
- Asp.Net Core 项目实战之权限管理系统(4) 依赖注入、仓储、服务的多项目分层实现
0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...
- 给缺少Python项目实战经验的人
我们在学习过程中最容易犯的一个错误就是:看的多动手的少,特别是对于一些项目的开发学习就更少了! 没有一个完整的项目开发过程,是不会对整个开发流程以及理论知识有牢固的认知的,对于怎样将所学的理论知识应用 ...
- asp.net core 实战之 redis 负载均衡和"高可用"实现
1.概述 分布式系统缓存已经变得不可或缺,本文主要阐述如何实现redis主从复制集群的负载均衡,以及 redis的"高可用"实现, 呵呵双引号的"高可用"并不是 ...
- Linux实战教学笔记08:Linux 文件的属性(上半部分)
第八节 Linux 文件的属性(上半部分) 标签(空格分隔):Linux实战教学笔记 第1章 Linux中的文件 1.1 文件属性概述(ls -lhi) linux里一切皆文件 Linux系统中的文件 ...
随机推荐
- 如何处理Express异常?
译者按:根据墨菲定律:“有可能出错的事情,就会出错”.那么,既然代码必然会出错,我们就应该处理好异常. 原文: How to handle errors in Express 译者:Fundebug ...
- nginx比apache处理静态文件速度快,但是nginx处理大量并发的php请求时,容易出现502错误,频率大概是多少
首先要明确一点的是502是怎么出现的,为什么会出现502呢? 一般而言,出现502的错误是因为php-cgi连接数不够导致的.举个例子:php-cgi开10个进程,前端发20个请求,每个请求的脚本都s ...
- 网页字体在Frontpage2000制作网页中的讲解
运用HTML,我们可以对字体的大小及字形进行简单的修改,但要进行统一地控制.创建特殊效果,就必须要用到CSS.它能让您更有效地控制网页外观,并可以扩充精确指定网页元素位置,外观以及创建特殊效果的能力. ...
- POJ1743 Musical Theme(后缀数组 二分)
Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 33462 Accepted: 11124 Description A m ...
- 洛谷P1337 [JSOI2004]平衡点 / 吊打XXX(模拟退火)
题目描述 如图:有n个重物,每个重物系在一条足够长的绳子上.每条绳子自上而下穿过桌面上的洞,然后系在一起.图中X处就是公共的绳结.假设绳子是完全弹性的(不会造成能量损失),桌子足够高(因而重物不会垂到 ...
- zTree 节点文字过多处理方法
zTree setting.view.addDiyDom 方法可以实现自定义控件,指定节点显示内容.因此需要自己实现addDiyDom方法. 如果树节点不显示checkbox ,处理方法为: func ...
- [CSS] Scale on Hover with Transition
效果 源码 <!doctype html> <html class="outline color"> <head> <meta chars ...
- 一年过去了,25万月薪的AI工程师还存在吗?
导读:2017 年的时候,AI 前线进行了一场有关人工智能领域薪资差异的专题策划,这篇名为<25 万年薪的你与 25 万月薪的他,猎头来谈你们之间的差别>的文章引起了读者们的热烈讨论.一年 ...
- Android--获取手机联系人和Sim卡联系人
最近公司做的一个放贷APP,要求后台偷偷获取用户的联系人来做风控,所以...(大家忽略就好) 获取手机联系人很简单,就是查询android的数据库,用到的是ContentProvider进行跨进程通讯 ...
- 我喜欢 Google Flutter
在 Google I/O ’17 上,Google 向我们介绍了 Flutter —— 一款新的用于创建移动应用的开源库. 正如你所想的那样,Flutter 是能够帮助创建拥有漂亮 UI 界面的跨平台 ...