梦入琼楼寒有月,行过石树冻无烟

Spring cloud 应用程序分层与响应式

MVC(Model-View-Controller)


MVC(Model View Controller)是在软件工程中较为常见的一种架构模式,无论是 Spring cloud 以及 Spring、Spring boot 基本上我们都介绍过此模型。

如果要简单的理解 MVC 的话,我们可以从上图了解到,首先 Model 是拥有对数据直接访问的权利(例如数据库访问)。

Conttroller 则是可以控制应用程序的流程,并对事件作出响应,这也包括了对 Model 的操作。

最后则是 View ,他能够显示资料,通常为前端应用。在上图中 Controller 操纵 Model 进行数据的更新或插入,之后交给 View 进行显示给用户。

如果说前面我们介绍的都是 MVC 概述,那么通过上图我们可以详细的进行理解。首先浏览器一看是看到的并不是 View,而是 通过 DispathcherServlet 来调用视图渲染后返回给浏览器中。这里我们需要注意的是 DispathcheServlet 继承于 HttpServlet ,主要负责协调和组织不同组件来完成请求并返回响应的工作,他的流程如下:

  1. 浏览器发送请求,服务器接受请求并转交给 DispatcherServlet 进行处理
  2. DispatcherServlet 匹配在控制器中配置的映射路径,进行下一步处理
  3. View 请求将 Model 和 View 解析成 View,之后调用 render() 方法根据 Model 和 View 中的数据渲染出页面。

三层架构

这与 MVC 的三层架构有很大的关系,所谓三层架构即 表现层(UI)、业务逻辑层(Service)、数据访问层(Dao\Repository)三种,他们分别表示:

Responsitory 是存取和管理对象,而 Dao 则是存取对象

  1. 表现层:用于展示界面,接收用户请求并返回数据,为客户端提供应用程序的访问接口(View)
  2. 业务逻辑层:也称之为服务层,负责业务逻辑的处理,主要调用D哦曾对数据进行 CURD 的操作
  3. 数据访问层:与数据库进行交互的持久层,被 Service 调用,在 Spring Data JPA 中则由 Hibernate 进行实现。

WebFlux

反应式是关于异步和事件驱动的非堵塞应用程序,并且需要少量线程进行垂直扩展,而不是水平扩展(集群)。反应式系统具有某些特征,可以使其成为低延迟、高吞度量工作的理想选择。

WebFlux 是在 Spring Framework 5.0(5.0.0.M5)所引入的一种反应式 Web 框架。WebFlux 可以在资源有限的情况下提高系统的吞度量和垂直扩展,这意味着在同样情况下 WebFlux 的吞吐量明显优于 MVC。

响应式(反应式)与命令式

为了应对高并发环境下服务端开发,微软提出了一个实现异步编程方案,即 反应式编程(Reactive Programming)。其他技术和社区为了跟上脚步,因此向 Netifix 等公司都也提供了类似的技术,这使得 Java 平台也有了能够实现反应式编程的框架

响应式编程或反应式编程(Reactive programming)是一个面向数据流和 变化传播 的声明式编程范式(Declarative programming)。

响应式编程与命令式编程对立,他的目标是让计算机明白,而非流程,声明式编程不需要告诉电脑问题,即告诉结果,让机器自行解决

而响应式编程则是是意味着式子 a=b+c,这意味着 a 是由 b 和 c 计算而出,如果后续有变化会影响到 a 的值,这也是 即告诉结果,让机器自行解决

命令式编程或指令式编程(Inperative programming),详细命令机器去处理一种事情而达到你想要的结果
变化传递我们可以理解为在命令式变成中,假设式子为 a=b+c 那么 a 的值就来自 b和c计算出的,如果后续有变化不会影响到a的值,这也是为什么他是 细命令机器去处理一种事情而达到你想要的结果

Spring WebFlux 是一个从头开始构建的非堵塞Web框架,可利用多核下一代处理器并处理大量并发。而 WebFlux 与 Spring MVC 数据流的选择也各不相同,前者是 Reactive Streames,后者则是 Servlet API


自然而然,既然 WebFlux 是用的是响应式数据流,而Spring MVC 选择的是 命令式数据流,自然而然 WebFlux 会更快。我认为上图很好的诠释了这一点,Spring MVC 是一个 响应 -> 准备数据 -> 返回数据 的一个过程。而 WebFlux 则是 响应 -> 返回数据 -> 开启一个新的 Work 线程进行准备 -> Work 线程完成工作 -> 返回结果 从而让对方觉得 WebFlux 会更快的一点。

Reactor

Peactor 框架由 Pivotal 基于 反应式编程(Reactive Programming) 思想进行实现,符合反应式编程的规范。

响应式编程

响应式编程(Reactive Programming)是一种非堵塞且事件驱动数据的开发方案,使用函数式编程的概念来操作数据流。

函数式编程是一种编程方式,将计算机的运算视为函数计算,如何直接和生动形象的表现出函数式编程的特点呢,那么下面的表达式就非常的清晰

过程式编程: var a = 1 + 2;
函数式编程: var result = subtract(multiply(add(1,2), 3), 4);

其实函数式变成并没有什么特殊,他其实就是将一数复制给变量或者一个数组中,就这个意思。
函数变成最主要的是λ演算 (Iambda calculus),而λ演算可以 接受函数党组输出(参数)和输出(返回值),相比过程化编程相比,函数式编程里的函数可以随时调用

事件 方法
包含元素信息 onNext()
序列结束消息 onComplete()
序列出错消息 onError()

这是通知与订阅者对应的方法,但如果我们继续眼神可以了解到背压机制(与本文有关):

事件 Iterable 迭代模式 (拉\pull) Observable 观察模式(推\push)
获取数据 T next() onNext()
处理完成 hasNext() onCompleted()
发现异常 throws Exception onError()

1.事件发布者(Publisher) 主动推送数据给 订阅者(Subscriber),出发 onNext() 方法;
2.事件发布者发生异常,则触发 订阅者 的 onError() 方法进行异常捕获处理
3.事件发布者每次推送都触发一次 onNext() 方法,当所有推送无异常时, onCompleted() 方法在在最后触发一次。

我们可以从被订阅者和订阅者理解为服务提供者和服务消费者。

如果 被订阅者发布的消息太快了,超过了订阅者的处理速度,那么这个时候就需要通过 背压机制(Backpressure),使得订阅者能够控制消费消息的速度。

实际上除了 迭代模式 (lterable) 其他的都是我们 响应式编程API的使用方式,实际上激素和观察者模式(Observable)的扩展。

Reactive Streams

他由 Netifix,TypeSafe、Pivatol共同制定,这是 Java 平台上 RxJava、Scala、Akka、Spring、Reactor 等项目的主要维护者所共同发起的。

反应式流(Reactive Streams)是一项倡议,主要用于反应式编程相关的规范以及接口提供标准。

他主要有四个组件构成,分别为发布者、订阅者、订阅、处理器等。除此还有三个接口最为主要:

  1. Publisher(事件发布者)
  2. Subscriber(订阅者)
  3. Subcription(订阅)

Mono 与 Flux

Mono 与 Flux 都是事件的发布者,也是 Reactor 的核心类:

如果根据 ID 查询某个 User 对象,那么返回的肯定是单个数据,那么就需要使用 Mono<User>

但是如果要获取所有 User,则返回的是多个数据,需要使用 Flux<User>

需要注意的是 Mono 与 Flux 之间可以 互相转换,对一个 Flux 序列进行技术操作,得到的结果是一个 Mono<Long> 对象,将多个 Mono 序列合并在一起,则得到的是 Flux 对象。

⬅️ Go back