WebFlux服务端开发

本文详细介绍了SpringWebFlux的基础知识,包括其非阻塞开发模式和高并发优势。接着讨论了异步Servlet的原因和实现方式,以及WebFlux的Mono和Flux对象实战。此外,还讲解了SSE(Server-Sent Events)的应用和响应式微服务的实例开发,包括MongoDB连接、参数校验以及RouterFunction模式的使用。

一.SpringWebFlux基础知识

1.概念
  • Spring5提出的新的开发Web的技术栈,非阻塞的开发模式,运行在netty或servlet3.1上,支持很高的并发量
  • 非阻塞的概念
    • WebFlux一个线程里可以处理更多的请求
    • 老的开发模式:一个请求会对应容器里的一个线程
  • 运行环境的不同
    • 老的开发模式:基于ServletAPI,即运行在Servlet容器上面
    • Webflux开发模式:基于响应式流,可以运行在Servlet3.1之后的容器(异步Servlet容器)或Netty上
  • 数据库的不同
    • 目前关系型数据库都是不支持响应式(基于JDBC)的数据库
    • Reactive stack的SpringDataReactiveRepositories是:Mongo,Cassandra,Redis,Couchbase
2. 开发优势
  • 支持高并发(异步非阻塞模式——垂直扩展)
    【题外知识:扩展分为两部分水平扩展和垂直扩展,水平扩展指的是人员和硬件设备的增加,垂直扩展只的是技术栈的变更】

二.异步Servlet

1.为什么要使用异步Servlet?同步Servlet阻塞了什么?
  • 同步Servlet代码
@WebServlet("/SyncServlet")
public class SyncServlet extends HttpServlet {
   
   
    public SyncServlet() {
   
   
        super();
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse) {
   
   
        //获取进入时时间
        long t1 = System.currectTimeMillis();
        //执行业务代码
        doSomeThing(request, response);
        //打印执行耗时
        System.out.println("Sync use:"+(System.currectTimeMillis()-t1));
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse) {
   
   
        doGet(request, response);
    }
    //耗时操作执行逻辑
    public void doSomeThing(HttpServletRequest request, HttpServletResponse) {
   
   
        //模拟耗时操作
        try {
   
   
            TimeUnit.SECONDS.sleep(5);//延迟5秒
        } catch(InterruptedException e) {
   
   }
        response.getWriter().append("done");
    }
}
//访问请求大约耗时5s
  • 同步Servlet阻塞了Tomcat容器的servlet线程。
  • 请求执行流程:当网络请求发送到Tomcat容器之后,Tomcat容器会给每一个请求创建一个线程去处理,线程里会调用指定Servlet去处理。当使用同步Servlet时,业务代码花多长时间,Servlet代码就要等多长时间。
  • 异步Servlet代码[不会阻塞Tomcat的Servlet线程]
@WebServlet(asyncSupported=true, urlPatterns={
   
   "/AsyncServlet"})
public class AsyncServlet extends HttpServlet {
   
   
    public AsyncServlet() {
   
   
        super();
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse) {
   
   
        //获取进入时时间
        long t1 = System.currectTimeMillis();
        //开启异步,获得异步执行的上下文
        AsyncContext asyncContext = request.startAsync();
        //使用JDK8的CompletableFuture.runAsync(()->...);的方式执行异步操作在不同线程里处理[执行业务代码,传递异步执行的上下文请求及响应]
        CompletableFuture.runAsync(()->doSomeThing(asyncContext,asyncContext.getRequest(), asyncContext.getResponse()));
        //打印执行耗时
        System.out.println("Async use:"+(System.currectTimeMillis()-t1));
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse) {
   
   
        doGet(request, response);
    }
    //耗时操作执行逻辑
    public void doSomeThing(AsyncContext asyncContext,ServletRequest request, ServletResponse) {
   
   
        //模拟耗时操作
        try {
   
   
            TimeUnit.SECONDS.sleep(5);//延迟5秒
        } catch(InterruptedException e) {
   
   }
        response.getWriter().append("done");
        //业务代码处理完毕,通知结束
        asyncContext.complete();
    }
}
//访问请求大约耗时16ms
2.异步Servlet怎样编写
  • 开启异步上下文
  • 将异步代码放到独立的线程池中执行
  • 调用异步上下文的complete()方法通知结束

三.WebFlux开发

1.Mono对象实战开发
  • 添加Reactive Web依赖

  • 实例代码

    @RestController
    public class TestController {
         
         
        @GetMapping("/1")
        private String get1() {
         
         
            return "some string";
        }
        @GetMapping("/2")
        private Mono<String> get2() {
         
         
            Mono<String>result = Mono.fromSupplier(()->"some string");
            //返回Mono不会阻塞线程,如果是耗时操作会异步执行
            
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值