zoukankan      html  css  js  c++  java
  • 一文带你了解 Spring 5.0 WebFlux 应用场景

    一、什么是 Spring WebFlux

    下图截自 Spring Boot 官方网站:

    Spring Boot 2.0 WebFlux 教程 | 入门篇

    结合上图,在了解 Spring WebFlux 之前,我们先来对比说说什么是 Spring MVC,这更有益我们去理解 WebFlux,图右边对 Spring MVC 的定义,原文如下:

    Spring MVC is built on the Servlet API and uses a synchronous blocking I/O architecture whth a one-request-per-thread model.

    翻译一下,意思如下:

    Spring MVC 构建于 Servlet API 之上,使用的是同步阻塞式 I/O 模型,什么是同步阻塞式 I/O 模型呢?就是说,每一个请求对应一个线程去处理。

    了解了 Spring MVC 之后,再来说说 Spring WebFlux:

    上图左边,官方给出的定义如下:

    Spring WebFlux is a non-blocking web framework built from the ground up to take advantage of multi-core, next-generation processors and handle massive numbers of concurrent connections.

    翻译一下,内容如下:

    Spring WebFlux 是一个异步非阻塞式的 Web 框架,它能够充分利用多核 CPU 的硬件资源去处理大量的并发请求。

    二、WebFlux 的优势&提升性能?

    WebFlux 内部使用的是响应式编程(Reactive Programming),以 Reactor 库为基础, 基于异步和事件驱动,可以让我们在不扩充硬件资源的前提下,提升系统的吞吐量和伸缩性。

    看到这里,你是不是以为 WebFlux 能够使程序运行的更快呢?量化一点,比如说我使用 WebFlux 以后,一个接口的请求响应时间是不是就缩短了呢?

    抱歉了,答案是否定的!以下是官方原话:

    Reactive and non-blocking generally do not make applications run faster.

    WebFlux 并不能使接口的响应时间缩短,它仅仅能够提升吞吐量和伸缩性

    三、WebFlux 应用场景

    上面说到了, Spring WebFlux 是一个异步非阻塞式的 Web 框架,所以,它特别适合应用在 IO 密集型的服务中,比如微服务网关这样的应用中。

    PS: IO 密集型包括:磁盘IO密集型, 网络IO密集型,微服务网关就属于网络 IO 密集型,使用异步非阻塞式编程模型,能够显著地提升网关对下游服务转发的吞吐量。

    WebFlux网关

    四、选 WebFlux 还是 Spring MVC?

    首先你需要明确一点就是:WebFlux 不是 Spring MVC 的替代方案!,虽然 WebFlux 也可以被运行在 Servlet 容器上(需是 Servlet 3.1+ 以上的容器),但是 WebFlux 主要还是应用在异步非阻塞编程模型,而 Spring MVC 是同步阻塞的,如果你目前在 Spring MVC 框架中大量使用非同步方案,那么,WebFlux 才是你想要的,否则,使用 Spring MVC 才是你的首选。

    在微服务架构中,Spring MVC 和 WebFlux 可以混合使用,比如已经提到的,对于那些 IO 密集型服务(如网关),我们就可以使用 WebFlux 来实现。

    选 WebFlux 还是 Spring MVC? This is not a problem!

    咱不能为了装逼而装逼,为了技术而技术,还要考量到转向非阻塞响应式编程学习曲线是陡峭的,小组成员的学习成本等诸多因素。

    总之一句话,在合适的场景中,选型最合适的技术

    五、异同点

    WebFlux 适用性

    从上图中,可以一眼看出 Spring MVC 和 Spring WebFlux 的相同点和不同点:

    相同点:

    • 都可以使用 Spring MVC 注解,如 @Controller, 方便我们在两个 Web 框架中自由转换;
    • 均可以使用 Tomcat, Jetty, Undertow Servlet 容器(Servlet 3.1+);
    • ...

    注意点:

    • Spring MVC 因为是使用的同步阻塞式,更方便开发人员编写功能代码,Debug 测试等,一般来说,如果 Spring MVC 能够满足的场景,就尽量不要用 WebFlux;
    • WebFlux 默认情况下使用 Netty 作为服务器;
    • WebFlux 不支持 MySql;

    六、简单看看 WebFlux 是如何分发请求的

    使用过 Spring MVC 的小伙伴们,应该到知道 Spring MVC 的前端控制器是 DispatcherServlet, 而 WebFlux 是 DispatcherHandler,它实现了 WebHandler 接口:

    WebFlux WebHandler接口

    来看看DispatcherHandler类中处理请求的 handle 方法:

    WebFlux handle 源码分析

    • ①:ServerWebExchange 对象中放置每一次 HTTP 请求响应信息,包括参数等;
    • ②:判断整个接口映射 mappings 集合是否为空,空则创建一个 Not Found 的错误;
    • ③:根据具体的请求地址获取对应的 handlerMapping;
    • ④:调用具体业务方法,也就是我们定义的接口方法;
    • ⑤:处理返回的结果;

    七、快速入门

    7.1 添加 webflux 依赖

    新建一个 Spring Boot 项目,新建步骤可参考笔者另一篇博文《Spring Boot 入门教程 | 图文讲解》,在 pom.xml 文件中添加 webflux 依赖:

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

    7.2 定义接口

    新建一个 controller 包,用来放置对外的接口类,再创建一个 HelloWebFluxController.class 类,定义两个接口:

    package site.exception.springbootwebfluxhello.controller;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    import reactor.core.publisher.Mono;
    import site.exception.springbootwebfluxhello.entity.User;
    
    /**
     * @author 犬小哈 (微信号: 小哈学Java)
     * @site 个人网站: www.exception.site
     * @date 2019/4/15
     * @time 下午9:12
     * @discription
     **/
    @RestController
    public class HelloWebFluxController {
    
        @GetMapping("/hello")
        public String hello() {
            return "Hello, WebFlux !";
        }
    
        @GetMapping("/user")
        public Mono<User> getUser() {
            User user = new User();
            user.setName("犬小哈");
            user.setDesc("欢迎关注我的公众号: 小哈学Java");
            return Mono.just(user);
        }
    
    
    }
    
    

    User.java:

    package site.exception.springbootwebfluxhello.entity;
    
    /**
     * @author 犬小哈 (微信号: 小哈学Java)
     * @site 个人网站: www.exception.site
     * @date 2019/4/15
     * @time 下午9:12
     * @discription
     **/
    public class User {
    
        /**
         * 姓名
         */
        private String name;
        /**
         * 描述
         */
        private String desc;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getDesc() {
            return desc;
        }
    
        public void setDesc(String desc) {
            this.desc = desc;
        }
    }
    

    以上控制器类中,我们使用的全都是 Spring MVC 的注解,分别定义了两个接口:

    • 一个 GET 请求的 /hello 接口,返回 Hello, WebFlux !字符串。
    • 又定义了一个 GET 请求的 /user 方法,返回的是 JSON 格式 User 对象。

    这里注意,User 对象是通过 Mono 对象包装的,你可能会问,为啥不直接返回呢?

    在 WebFlux 中,Mono 是非阻塞的写法,只有这样,你才能发挥 WebFlux 非阻塞 + 异步的特性。

    补充:在 WebFlux 中,除了 Mono 外,还有一个 Flux,这哥俩均能充当响应式编程中发布者的角色,不同的是:

    • Mono:返回 0 或 1 个元素,即单个对象。
    • Flux:返回 N 个元素,即 List 列表对象。

    7.3 测试接口

    启动项目,查看控制台输出:

    启动 WebFlux 项目

    当控制台中输出中包含 Netty started on port(s): 8080 语句时,说明默认使用 Netty 服务已经启动了。

    打开浏览器,先对 /user 接口发起调用:

    请求 /hello 接口

    返回成功。

    再来对 /user 接口测试一下:

    请求 /user 接口

    返回 JSON 格式的 User 实体也是 OK 的!

    八、总结

    本文中,我们学习了什么是 Spring WebFlux, WebFlux 的优势和应用场景,接下来我么谈了谈在我们生产环境中技术选型该选 WebFlux 还是 Spring MVC, 两者之间又有什么异同点,以及从源码角度了解了 WebFlux 是如何分发请求的。

    最后上手操作写了两个简单的接口,并测试成功了。

    下一章中,我们将进一步学习,如何在 WebFlux 中对数据库做增删改查操作,敬请期待吧!

    九、GitHub 示例代码

    https://github.com/weiwosuoai/spring-boot-tutorial/tree/master/spring-boot-webflux-hello

    十、Ref

    赠送 | 面试&学习福利资源

    最近在网上发现一个不错的 PDF 资源《Java 核心知识&面试.pdf》分享给大家,不光是面试,学习,你都值得拥有!!!

    获取方式: 关注公众号: 小哈学Java, 后台回复 资源,既可免费无套路获取资源链接,下面是目录以及部分截图:

    关注微信公众号【小哈学Java】,回复【资源】,即可免费无套路领取资源链接哦

    关注微信公众号【小哈学Java】,回复【资源】,即可免费无套路领取资源链接哦

    关注微信公众号【小哈学Java】,回复【资源】,即可免费无套路领取资源链接哦

    关注微信公众号【小哈学Java】,回复【资源】,即可免费无套路领取资源链接哦

    关注微信公众号【小哈学Java】,回复【资源】,即可免费无套路领取资源链接哦

    关注微信公众号【小哈学Java】,回复【资源】,即可免费无套路领取资源链接哦

    重要的事情说两遍,关注公众号: 小哈学Java, 后台回复 资源,既可免费无套路获取资源链接 !!!

    欢迎关注微信公众号: 小哈学Java

    小哈学Java

  • 相关阅读:
    SQL Server数据库中批量替换数据的方法
    js 鼠标移上去弹出层效果
    50个jQuery代码段帮你成为更好的JavaScript开发者
    MSN、腾讯QQ、SKYPE、阿里旺旺网页在线客服源代码
    正则表达式基础知识
    常用邮箱POP3和SMTP服务器汇总
    CS5序列号
    如何使用Oracle SQLDeveloper 中连接MS SQLServer和MySQL数据库
    Silverlight与后台数据库的三种技术实现基本的互操作(转)
    ADO 与ADO.NET
  • 原文地址:https://www.cnblogs.com/quanxiaoha/p/10773773.html
Copyright © 2011-2022 走看看