`
valiant025
  • 浏览: 17068 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

Spring Boot : 响应式编程以及 Spring Boot Webflux 快速入门

 
阅读更多

 

Spring Boot (十四): 响应式编程以及 Spring Boot Webflux 快速入门
 

 

1. 什么是响应式编程

在计算机中,响应式编程或反应式编程(英语:Reactive programming)是一种面向数据流和变化传播的编程范式。这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。

(了解源码可+求求: 1791743380)

例如,在命令式编程环境中,a=b+c 表示将表达式的结果赋给 a,而之后改变 b 或 c 的值不会影响 a 。但在响应式编程中,a 的值会随着 b 或 c 的更新而更新。

响应式编程是基于异步和事件驱动的非阻塞程序,只需要在程序内启动少量线程扩展,而不是水平通过集群扩展。

设想一个场景,从底层数据库驱动,经过持久层、服务层、MVC层中的model,到用户的前端界面的元素,全部都采用声明式的编程范式,从而搭建一条能够传递变化的管道,这样我们只要更新一下数据库中的数据,用户的界面上就相应的发生变化,从而无需前端轮询才能获取到最新的数据。

简单来讲,我们以前写的程序是阻塞式的,当一个请求任务过来时,线程会阻塞,等到这个任务完成后再返回出去。而响应式编程则是一个请求任务过来时,会有其他的线程去做处理,当任务执行结束后再异步的通知回去。

2. 为什么要使用响应式编程

在如今互联网时代的大背景下,Web应用通常要面对高并发、海量数据的挑战,性能从来都是必须要考量的核心因素。

阻塞便是性能杀手之一。

多数人不认为阻塞是一个比较大的问题,至少觉得除了网络I/O之外,读写文件和数据库还是很快的,许多人也一直在写阻塞的代码。

那么 I/O 操作具体有多慢?

2.1 CPU眼中的时间

CPU绝对称得上是“闪电侠”,因为它们做事都有自己的一套时钟。我们故事的主人公是一个主频为2.5GHz的CPU,如果它的世界也有“秒”的概念,并且它的时钟跳一下为一秒,那么在CPU(CPU的一个核心)眼中的时间概念是啥样的呢?

CPU先生所在的组是硬件部计算组。对它来说,与其一起紧密合作的几个小伙伴还能跟的上它的节奏:

  • CPU先生很利索,只需要一秒就可以完成一个指令,复杂的动作可能需要多个指令。
  • 好在“贴身秘书”一级缓存反应比较快,能够秒懂CPU先生的意思。
  • 来自“秘书组”的二级缓存虽然要十几秒才能“get”到CPU先生的点,但也不算太迟钝。
  • 和内存组的合作已经习以为常了,跟内存请求的数据通常要4-5分钟才能找到(内存寻址),不过也还好啦,毕竟一级缓存那里能拿到80%想要的数据,其余的二级缓存也能搞定一大部分,不怎么耽误事儿。

CPU先生是典型的工作狂,任务多的时候,通宵达旦也毫无怨言,但是有什么事情让它等,那简直要他命了。恰恰一起共事的其他组(尤其是I/O组的磁盘和网卡)相对来说那效率是低的离谱啊:

  • 关于I/O组的同事,CPU先生已经抱怨很久了,每次找SSD要东西,都要花费4-5天才能找到(寻址),等到数据传送过来,几周都过去了。机械磁盘更是过分地离谱,跟他要个数据,竟然要平均花费10个月才能找到,如果要读取1M的数据,竟然要20个月!这种员工怎么还不下岗?!
  • 关于网卡,CPU先生知道它们也尽力了,毕竟万兆网络成本颇高。与机房内的其他小伙伴们用千兆网络互相沟通也算顺畅,给另一台机器的CPU朋友发送1K的书信,最快七八个小时就可以送过去了。但是1K的书信经过层层包裹,实际也写不了多少话。更要命的是,网卡们的沟通手续繁杂,每次网络沟通前的 “你好能听到我吗?——我能听到,你那边能听到我吗?——我也能听到你,那我们开始吧!” 这样的握手确认都要花掉很长的时间,不过不能当面沟通,也只能这样了。这还好,最恐怖的是与其他城市的小伙伴沟通,有时候传递消息要花费好几年呢!

由此可见,对于CPU先生来说,想要让工作充实起来实在不容易,不过多亏了内存组的小伙伴帮忙分批缓存往返于I/O组的数据,矛盾才有所缓解。

 

Spring Boot (十四): 响应式编程以及 Spring Boot Webflux 快速入门
 

 

这个图只能明显看出涉及I/O的时间条,我们转换成对数刻度的图看一下:

 

Spring Boot (十四): 响应式编程以及 Spring Boot Webflux 快速入门
 

 

这个图并不是直观的比例,横轴上每个刻度是一个数量级,可见I/O的速度与CPU和内存相比是要差几个数量级的。由此可见,对于大型高并发场景下的Web应用,缓存有多重要,更高的缓存命中率就意味着性能。

  1. 并行化:使用更多的线程和硬件资源;
  2. 异步化:基于现有的资源来提高执行效率。

3. 基础概念

在介绍主题之前先普及几个概念:

3.1 Backpressure(背压)

背压是一种常用策略,使得发布者拥有无限制的缓冲区存储元素,用于确保发布者发布元素太快时,不会去压制订阅者。

3.2 Reactive Streams(响应式流)

一般由以下组成:

  • 发布者:发布元素到订阅者
  • 订阅者:消费元素
  • 订阅:在发布者中,订阅被创建时,将与订阅者共享
  • 处理器:发布者与订阅者之间处理数据

3.3 Mono 和 Flux

  • Mono:实现发布者,并返回 0 或 1 个元素
  • Flux:实现发布者,并返回 N 个元素

4. Spring Webflux

Spring Boot Webflux 是基于 Reactor 实现的。Spring Boot 2.0 包括一个新的 spring-webflux 模块。该模块包含对响应式 HTTP 和 WebSocket 客户端的支持,以及对 REST,HTML 和 WebSocket 交互等程序的支持。一般来说,Spring MVC 用于同步处理,Spring Webflux 用于异步处理。

Spring Boot Webflux 有两种编程模型实现,一种类似 Spring MVC 注解方式,另一种是使用其功能性端点方式。

4.1 适用性

 

Spring Boot (十四): 响应式编程以及 Spring Boot Webflux 快速入门
 

 

一图就很明确了,WebFlux 和 MVC 有交集。但是注意:

  • MVC 能满足场景的,就不需要更改为 WebFlux。
  • 要注意容器的支持,可以看看下面内嵌容器的支持。
  • 微服务体系结构,WebFlux 和 MVC 可以混合使用。尤其开发 IO 密集型服务的时候,选择 WebFlux 去实现。

4.2 内嵌容器

跟 Spring Boot 大框架一样启动应用,但 WebFlux 默认是通过 Netty 启动,并且自动设置了默认端口为 8080。另外还提供了对 Jetty、Undertow 等容器的支持。开发者自行在添加对应的容器 Starter 组件依赖,即可配置并使用对应内嵌容器实例。

但是要注意,必须是 Servlet 3.1+ 容器,如 Tomcat、Jetty;或者非 Servlet 容器,如 Netty 和 Undertow。

4.3 数据库

支持 reactive 编程的数据库只有 MongoDB , redis , Cassandra , Couchbase 。

4.4 快速上手

工程依赖

代码清单:spring-boot-webflux/pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

 

Service 类

代码清单:spring-boot-webflux/src/main/java/com/springboot/springbootwebflux/service/impl/UserServiceImpl.java

@Service
public class UserServiceImpl implements UserSerivice {

    private static Map<Long, User> map = new HashMap<>();

    static {
        map.put(1L, new User(1L, "www.geekdigging.com", 18));
        map.put(2L, new User(2L, "极客挖掘机", 28));
    }

    @Override
    public Mono<User> getUserById(Long id) {

        return Mono.just(map.get(id));
    }
}

 

Controller 类

代码清单:spring-boot-webflux/src/main/java/com/springboot/springbootwebflux/controller/UserController.java

@RestController
public class UserController {

    @Autowired
    UserSerivice userSerivice;

    @GetMapping("/getUserById/{id}")
    public Mono<User> getUserById(@PathVariable Long id) {
        return userSerivice.getUserById(id);
    }
}

 

通过上面的示例可以发现,开发模式和之前 Spring MVC 的模式差别不是很大,只是在方法的返回值上有所区别。

分享到:
评论

相关推荐

    alex2chen#spring-boot-cloud-note#spring5:响应式编程-WebFlux 1

    响应式宣言We want systems that are Responsive, Resilient, Elastic and Message Driven.

    Spring Boot 2核心技术 Spring Boot 2响应式编程 学习资料 -熟悉Spring基础 -熟悉Maven

    Spring Boot 2响应式编程 学习要求 -熟悉Spring基础 -熟悉Maven使用 基于SpringBoot2.3与2.4版本讲解,适用于有Spring、SpringMVC基础,初学或想深入了解SpringBoot的学习者。 教程包含核心基础、Web原理、单元测试...

    轻松上手Spring Boot:打造现代微服务的实战指南

    - **Spring WebFlux集成**:自 Spring Boot 2.x 版本起,支持响应式编程模型。 - **非阻塞处理**:利用非阻塞 I/O 提高应用性能。 13. **模板引擎** - **集成Thymeleaf/Freemarker**:Spring Boot 可以轻松集成 ...

    Spring Webflux 响应式编程 (二) - WebFlux编程实战

    结合Spring Boot,可以快速构建响应式微服务。 总结,Spring WebFlux响应式编程模型为开发者提供了全新的Web服务开发方式,通过Reactor库和非阻塞I/O模型,实现了高效、灵活的事件驱动编程。无论是对于新项目的构建...

    learning spring boot 2.0

    3. 响应式编程的实践,响应式系统的设计原则以及如何利用Spring WebFlux和Spring Data等模块构建响应式应用。 4. Java语言作为Spring Boot应用开发的核心技术。 5. Spring框架的深入应用,如何在Spring Boot中集成和...

    spring-boot-configuration-processor-2.3.12.RELEASE-API文档-中文版.zip

    赠送jar包:spring-boot-configuration-processor-2.3.12....Maven坐标:org.springframework.boot:spring-boot-configuration-processor:2.3.12.RELEASE; 标签:springframework、boot、spring、configuration、proc

    Spring Boot:加速现代Java应用开发的利器.pdf

    ### Spring Boot:加速现代Java应用开发的利器 #### 一、Spring Boot简介:为何选择它? Spring Boot作为Spring框架下的一个重要子项目,自发布以来便迅速成为Java开发者的首选工具。它通过简化Spring应用的创建、...

    Learning Spring Boot 英文版

    从该书的标题和内容来看,它是一本适合初学者的入门教材,涵盖的范围很广,包括Spring Boot的安装、配置、编码、测试以及部署等各个方面的知识。书籍的作者是Greg L. Turnquist,他被认为是Spring Boot方面的专家,...

    2023最新《Spring Boot基础教程》

    Spring Boot 2.x基础教程:快速入门 Spring Boot 2.x基础教程:工程结构推荐 配置详解 Spring Boot 2.x基础教程:配置文件详解 Spring Boot 2.x基础教程:2.4版本前后的多环境配置变化 Spring Boot 2.x基础教程:2.4...

    spring-boot-2.3.12.RELEASE-API文档-中文版.zip

    Maven坐标:org.springframework.boot:spring-boot:2.3.12.RELEASE; 标签:springframework、boot、spring、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览...

    009 maven插件spring-boot-maven-plugin

    spring-boot:repackage 是 Spring Boot Maven Plugin 提供的一个 Goal,用于重新打包可执行的存档。该 Goal 需要指定以下参数: * finalName:存档的名称 * classifier:存档的分类器 * outputDirectory:存档的...

    Spring Boot 2 一步一步学微服务项目实战

    Spring Boot 2 一步一步学微服务项目实战 出版时间:2018-08-01

    Spring boot 示例 官方 Demo

    spring-boot-helloWorld:spring-boot的helloWorld版本 spring-boot-mybaits-annotation:注解版本 spring-boot-mybaits-xml:xml配置版本 spring-boot-mybatis-mulidatasource:springboot+mybatis多数据源最简解决...

    Spring Boot:SpringBoot核心配置详解.docx

    Spring Boot:SpringBoot核心配置详解.docx

    Pro Spring Boot 2第2版-2009-EPUB版

    It will also cover what's been added to the new Spring Boot 2 release, including Spring Framework 5 features like WebFlux, Security, Actuator and the new way to expose Metrics through Micrometer ...

    spring-boot实战PDF 完整版和随书源码.7z

    《Spring Boot实战》是一本深度剖析Spring Boot框架的实践指南,旨在帮助开发者快速掌握Spring Boot的核心概念和技术。这本书深入浅出地介绍了如何使用Spring Boot构建高效、简洁的Java应用程序。随书源码提供了丰富...

    Spring Boot 教程、技术栈示例代码,快速简单上手教程。

    Spring Boot 是一个由 Pivotal 团队开发的框架,旨在简化 Spring 应用程序的初始搭建以及开发过程。它集成了大量常用的第三方库配置,如 JDBC、MongoDB、RabbitMQ、Quartz 等,使得开发者可以“零配置”地启动项目,...

    Spring Boot 进阶笔记(详细全面) 中文PDF完整版.pdf

    2. **起步依赖(Starter POMs)**:Spring Boot 提供了一系列的起步依赖,如 `spring-boot-starter-web`,这些依赖包含了开发特定功能所需的所有依赖,方便开发者快速集成。 3. **内嵌服务器**:Spring Boot 内置了...

    spring boot资料以及项目

    这个压缩包包含了丰富的Spring Boot学习资料以及实际项目案例,是深入理解和掌握Spring Boot技术的宝贵资源。 首先,让我们从基础开始。Spring Boot的核心理念是“约定优于配置”,它通过默认配置和自动配置,使得...

    Spring Boot实战 ,丁雪丰 (译者) 1

    此外,Spring Boot还支持Spring Boot CLI,Groovy,Grails以及Actuator,Actuator用于提供应用监控和管理功能。 Spring Boot的核心优势在于它针对运维工作的优化。例如,它简化了部署过程,提供了丰富的监控和度量...

Global site tag (gtag.js) - Google Analytics