WebFlux01 webflux概念、异步servlet、WebFlux意义
1 概念
待更新......
2 异步servlet
2.1 同步servlet
servlet容器(如tomcat)里面,每处理一个请求会占用一个线程,同步servlet里面,业务代码处理多久,servlet容器的线程就会等(阻塞)多久,而servlet容器的线程是有上限的,当请求多了的时候servlet容器线程就会全部用完,就无法再处理请求(这个时候请求可能排队也可能丢弃,得看如何配置),就会限制了应用的吞吐量!(来源:慕课网)
2.2 异步servlet
异步serlvet里面,servlet容器的线程不会傻等业务代码处理完毕,而是直接返回(继续处理其他请求),给业务代码一个回调函数(asyncContext.complete()),业务代码处理完了再通知我!这样就可以使用少量的线程处理更加高的请求,从而实现高吞吐量!(来源:慕课网)
2.3 同步servlet代码实现
2.4 异步servlet代码实现
3 WebFlux意义
WebFlux可以实现高并发,因为使用WebFlux框架时,当前端请求过来后不会占用Servlet容器的线程,Servlet容器在接收到请求后会通知Spring框架进行处理,然后释放掉线程供其他请求使用,等到Spring框架执行完业务逻辑后,Spring框架会通知Servlet容器,Servlet再将响应信息发送到前台
3.1 传统MVC和WebFlux比较
技巧01:WebFlux也可以实现创痛的MVC的请求,只需要响应数据不是Mono类型或者Flux类型就可以啦
3.1.1 项目构建
创建一个SpirngBoot项目(本博文基于2.0.3),引入 webflux、lombok、devtools依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <!--<scope>runtime</scope>--> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
3.1.2 创建一个测试类
该测试类用来对比创痛MVC和WebFlux的对比
》创建一个模拟业务方法(通过延时来实现业务逻辑的执行时间)
》传统MVC请求处理方法
》WebFlux请求处理方法
》代码汇总
package cn.xiangxu.webflux_demo.web; 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.Mono; import java.util.concurrent.TimeUnit; /** * @author 王杨帅 * @create 2018-08-01 16:26 * @desc 测试控制层 **/ @RestController @RequestMapping(value = "/test") @Slf4j public class TestController { @GetMapping(value = "/test01") public String test01() { log.info("mvc-start"); String result = doSomething("MVC"); log.info("mvc-end"); return result; } @GetMapping(value = "/test02") public Mono<String> test02() { log.info("mono-satar"); Mono<String> result = Mono.fromSupplier(() -> doSomething("Mono")); log.info("mono-end"); return result; } public String doSomething(String s) { try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } return "Hello " + s; } }
》效果演示
技巧01:同步和异步都是针对后台而言,浏览器都是同步的
传统的MVC模式会阻塞Servlcet容器线程,业务逻辑执行多久Servlet线程就会被占用多久;WebFlux模式不会占用Servlet线程,请求到达控制层后就会释放线程;只一点从日志打印的时间可以看出:
3.2 WebFlux的流式返回
利用Flux可以实现流一样的向前端发送数据
技巧01:请求方法上需要利用 produces 指明数据的响应类型,例如 ->
@GetMapping(value = "/test03", produces = MediaType.TEXT_EVENT_STREAM_VALUE)