开发经验为什么gateWay网关要用webFlux代替WebMvc

Posted 叁滴水

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开发经验为什么gateWay网关要用webFlux代替WebMvc相关的知识,希望对你有一定的参考价值。

      看过gateWay源码的都知道,它的底层使用的WebFlux。
     WebFlux会比传统的MVC更快?如果是这样,为什么平时开发不用这个?带着这个疑惑我翻了大把的资料,全是异步编程,全是快,异步等。但是一个机器的资源就这么多,它又是如何更快的呢?如果快的话,为什么平时没人用呢?通过如下这个案例,来说一下我的理解。

测试案例1

设置当前服务工作线程数为1,通过普通的同步写法,请求到接口。

 public static void main(String[] args) 
       // 设置当前工作线程为1.
        System.setProperty("reactor.netty.ioWorkerCount","1");
        SpringApplication.run(GatewayApplication.class, args);
    
    @GetMapping("/test3")
    public String stringMono3()
        logger.info("threadName:",Thread.currentThread().getName());
        return  "1";
    
    @GetMapping("/test4")
    public String stringMono4()
         logger.info("threadName:",Thread.currentThread().getName());
        try 
            Thread.sleep(10000);
         catch (InterruptedException e) 
            e.printStackTrace();
        
        return  "1";
    

快速的请求test4test3接口(保证先请求test4)日志如下:

2022-11-11 11:23:01.697  INFO 61844 --- [ctor-http-nio-1] c.m.gateway.handler.FollBackController   : threadName:reactor-http-nio-1
2022-11-11 11:23:11.704  INFO 61844 --- [ctor-http-nio-1] c.m.gateway.handler.FollBackController   : threadName:reactor-http-nio-1

        仔细观察日志打印时间,可以看出当只有一个线程的时候,test4通过sleep方法让线程休眠,在休眠期间,该线程不做任何事情,导致请求test3接口时,也会等待很久。

        这样可以想到,在真实场景中,如果有太多的这种阻塞操作,大量的线程在等待,会大量浪费计算机资源。能不能有一种方式,不让其等待呢?好比这个人没事的时候,就去干会别的活呢?

测试案例2

    @GetMapping("/test2")
    public Mono<String> stringMono2()
        Mono<String> log = WebClient.create().post().uri("http://localhost:8080/test/sleep10").retrieve().bodyToMono(String.class);
        logger.info("threadName:",Thread.currentThread().getName());
        return  log;
    
    @GetMapping("/test3")
    public String stringMono3()
        logger.info("threadName:",Thread.currentThread().getName());
        return  "1";
    

通过reactor来测试阻塞代码块。

  1. test2接口为请求一个响应时长为10秒的接口。然后打印线程名
  2. test3为直接打印线程名。

快速请求两个接口。日志打印如下:

2022-11-11 16:31:11.611  INFO 27436 --- [ctor-http-nio-1] c.m.gateway.handler.FollBackController   : threadName:reactor-http-nio-1
2022-11-11 16:31:12.797  INFO 27436 --- [ctor-http-nio-1] c.m.gateway.handler.FollBackController   : threadName:reactor-http-nio-1

        从日志打印可以看出,线程1,在执行test/sleep10接口时,还执行了test3的方法。这就是非阻塞的概念。当线程进入等待状态时(如:http接口响应等待),可以做其它的事情。这样就可以用少量的线程做更多的事。

问题:为什么reactor这么好,不用他代替mvc模式呢?

        个人以为,有两点原因。第一,一般我们的服务可以分为io密集型和cpu密集型。reactor模型在IO密集可以发挥出其优势。如网关,细想,gateway网关大部分都是在等待响应然后发挥,线程大把的时间处于等待,因此通过reactor编程可以更好的发挥其性能。第二,reactor学习成本高,不方便调试,用此框架时,需要多并发编程、nio等内容熟悉。

以上是关于开发经验为什么gateWay网关要用webFlux代替WebMvc的主要内容,如果未能解决你的问题,请参考以下文章

第二代网关GateWay搭建流程

gateway&reactive(响应式流)函数编程的webflux

开发经验gateway网关开发调试优先选择本地服务

开发经验gateway网关开发调试优先选择本地服务

SpringCloud-Gateway 网关路由断言过滤

第二代微服务网关组件 - Spring Cloud Gateway