大号在练葵花宝典 发表于 2024-8-24 03:45:33

响应式框架WebFlux架构和原理介绍

WebFlux简介

WebFlux是什么?

一个响应式的MVC框架。
https://img-blog.csdnimg.cn/direct/27ac70314a124ef386c990e62dd7300a.png
官网地点:https://docs.spring.io/spring-framework/docs/6.0.6/reference/html/web-reactive.html#webflux
什么是响应式程序

响应式处理是一种范式,使开辟人员可以大概构建可以大概处理背压(流量控制)的非壅闭异步应用程序。 详见官网:https://spring.io/reactive
为什么利用响应式程序

响应式系统更好地利用现代处理器。此外,在反应式编程中包罗背压可确保解耦组件之间具有更好的弹性。
SpringBoot 中的响应式架构图

响应式系统具有某些特性,使其成为低延迟、高吞吐量工作负载的抱负选择。Project Reactor和Spring产物组合协同工作,使开辟人员可以大概构建响应性、弹性、弹性和消息驱动的企业级反应系统。
https://img-blog.csdnimg.cn/direct/1612dee3c033494c80f9bd22895b219c.png
开辟利用 Spring MVC 照旧 WebFlux?

https://img-blog.csdnimg.cn/direct/eecec29d5fb2461484acf3c301d48045.png
这是一个很自然的问题,但却建立了一种不公道的二分法。究竟上,两者共同积极扩大了可用选项的范围。两者的设计是为了相互的连续性和同等性,它们可以并排利用,双方的反馈对双方都有利。下图显示了两者之间的关系、它们的共同点以及各自唯一支持的内容:
特点

响应式宣言(The Reactive Manifesto)


[*]快速响应(Responsive)
系统在各种情况下都会尽全力保证及时响应。它是可用性和实用性的基础, 还意味着问题能被迅速发现,并得到有效处理。
[*]回弹性(Resilient)
系统在面临故障时依然保持快速响应。它是通过复制(replication)、克制(containment)、隔离(isolation)和委托(delegation)来实现的。故障被克制在单个组件中, 且各组件相互隔离, 使系统在部门失败和规复时,可以不影响团体的功能。每个组件的规复都委托给另一个(外部)组件, 高可用在必要时通过复制来保证。
[*]可伸缩性(Elastic)
系统在不同的负载下都能保持快速的响应。响应式系统可以根据服务的哀求量, 动态增加或减少相应的资源。
[*]消息驱动(Message Driven)
响应式系统依赖异步的消息通报, 以确定各种组件的界限, 并确保松耦合(loose coupling)、隔离性(isolation)、位置透明性(location transparency), 并提供将错误封装为消息的手段。
WebFlux的特点


[*] 异步和非壅闭
支持了应用层的异步和底层的IO非壅闭。在应用层,利用Reactive Stream界说的异步组件,实现了异步调用。在底层,默认利用了Netty的NIO,实现了(同步)非壅闭。这不会使程序运行更快,但是可以用少量的线程蒙受住高负载,节省线程内存资源和减少线程上下文切换CPU耗时,进而提升吞吐量。
[*] 函数式编程
利用Lambda表达式和函数式接口来界说哀求处理程序。WebFlux.Fn是一种轻量级函数式编程模型,其中函数用于路由和处理哀求,契约设计为不可变。它是基于注释的编程模型的另一种选择,但在其他方面运行在类似的Reactive Core基础上。例如,RouterFunction相当于@RequestMapping注释。
[*] 去servlet
答应可以不基于servlet API。
默认的Netty容器,不基于Servlet API。Servlet3.1支持了异步、非壅闭通讯,因此,也可以选择利用Tomcat等容器,走Servlet API,但是,必须要利用WebFlux的框架代码。
代码实现

maven配置

<!-- WebFlux -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Controller 接口

import com.demo.service.DemoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;

@Slf4j
@RestController
@RequestMapping("/flux")
public class DemoController {

    @Resource
    private DemoService demoService;

    /**
   * webflux接口测试(返回 0个 或 1个结果)
   */
    @GetMapping("/monoTest")
    public Mono<Object> monoTest() {
      /// 写法一:命令式写法
//      String data = getOneResult("monoTest()");
//      return Mono.just(data);

      // 写法二:响应式写法(语句需要在流中执行)
      return Mono.create(cityMonoSink -> {
            String data = demoService.getOneResult("monoTest()");
            cityMonoSink.success(data);
      });
    }

    /**
   * webflux接口测试(返回 0个 或 多个结果)
   */
    @GetMapping("/fluxTest")
    public Flux<Object> fluxTest() {
      // 写法一:命令式写法
//      List<String> list = getMultiResult("fluxTest()");
//      return Flux.fromIterable(list);

      // 写法二:响应式写法(语句需要在流中执行)
      return Flux.fromIterable(demoService.getMultiResult("fluxTest()"));
    }

}



理论支持

阿姆达尔定律

系统中对某一部件采用更快执行方式所能获得的系统性能改进程度,取决于这种执行方式被利用的频率,或所占总执行时间的比例。它指出了并行可以提升加快比,依此多核多线程可以提速。也指出了加快比是由慢的(串行的)系统部件所限制。
通用可伸缩性定律

阿姆达尔定律表明了可伸缩性,但是现实应用程序并不完全符合此定律,当并发线程比CPU核数多得多时,吞吐量反而会下降。因此,在通用可伸缩性定律(简称USL)中,引入了CONTENTION (竞争)和COHERENCY(同等性):


[*]CONTENTION 表现由于共享资源的等待或列队。
[*]COHERENCY 表现由于分布式资源之间的点对点数据交换导致数据变得同等或缓存同等的延迟。
原理

观察者模式

观察者模式是经典的设计模式之一。被观察者发生改变时,通知所有的观察者,从而解耦被观察者和观察者。在WebFlux的Reactive Stream的实现中,利用了观察者模式。
背压

背压(Backpressure)是WebFlux中用于解决生产者和消耗者之间的速率不匹配问题的一种机制。当生产者的速率快于消耗者的处理速率时,背压机制答应消耗者告知生产者自己的处理本领,从而使生产者根据消耗者的处理本领来调解数据的生产速率,以避免数据的积压和丢失。背压的实现主要依赖于Reactor库中的Flux和Mono两个类,这两个类都提供了一系列的操作符,用于处理数据流,而且支持背压机制。
https://img-blog.csdnimg.cn/direct/4cc28facf0f14fc8a2992d2a922ca34b.png
WebFlux的初始化过程中,会去Spring上下文中找名为“webHandler”的WebHandler实现。默认情况下,Spring会在上下文中初始化一个DispatcherHandler的实现,Bean的name就是“webHandler”。这个内里维护了一个HandlerMapping列表,当哀求过来时会迭代HandlerMapping列表,返回一个WebHandler处理。
WebFlux支持控制器和路由器模式的编码,因为他们分别有实现的HandlerMapping,可以大概在WebHandler的handler里路由到详细的业务方法里。通过@Controller和@ResultMaping界说的接口信息,WebFlux实现了在Spring WebFlux里的魂魄一样的存在。
总结

官网:WebFlux并不能使接口的响应时间缩短,它仅仅可以大概提升吞吐量和伸缩性。
现实,高并发下,BIO高并发的响应时间会变长,而WebFlux的均匀响应时间相对稳固,结果如同缩短了响应时间。

[*]适用于IO麋集型场景,主要是指网络IO麋集
例如:微服务网关,网关用http举行服务转发,得当利用webClient实现非壅闭调用。
[*]不适用于CPU麋集型场景
https://img-blog.csdnimg.cn/direct/c1acfaf0d31a4023acfdaa00d430e304.png
注:部门图片引用自网络,侵删。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 响应式框架WebFlux架构和原理介绍