美文网首页
异步Servlet 特性

异步Servlet 特性

作者: Aska小强 | 来源:发表于2020-03-06 09:08 被阅读0次

    异步Servlet

    本篇主要讲解 如何使用 异步Servlet的处理请求,并且演示 同步Servlet和异步Servlet的区别,以及异步Servlet带来哪些好处 。

     1.需要解决的问题

    • 1.为什么使用异步Servlet? 同步Servlet阻塞了什么
    • 2.异步Servlet编写流程

     2.同步Servlet

     同步Servlet是指 tomcat线程去执行 servlet方法后,会一直被阻塞,直到业务代码执行完毕 ,这样tomcat 吞吐量就有限

     直接看代码,应该都很熟悉 同步Servlet的开发吧,

    /**
    * 同步Servlet 样例
    * @author johnny
    */
    @WebServlet(name = "Sync-SyncServlet", urlPatterns = "/sync")
    @Slf4j
    public class SyncServlet extends HttpServlet {
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        log.info("doPost sync servlet");
    }
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        long start = System.currentTimeMillis();
    
        try {
            //模拟业务代码处理
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    
        long end = System.currentTimeMillis();
        log.info("doGet sync servlet 耗时: {} 秒", (end - start) / 1000);
    
      }
    }
    
    Xnip20200225_161959.png

     3.异步Servlet

     异步Servlet主要是要注意

    • 1.开启异步Servlet asyncSupported = true
    • 2.获取异步上下文 AsyncContext asyncContext = request.startAsync();
    • 3.将业务耗时方法放入 线程池中去异步执行 注意需要传入异步上下文,供业务方法内部调用,如
        CompletableFuture.runAsync(() -> {
            doSomeThing(asyncContext, asyncContext.getRequest(), asyncContext.getResponse());
        });
    
    • 4.业务方法调用上下文结束 asyncContext.complete();
        /**
        * 异步Servlet 案例
        *
        * @author johnny
        * <p>
        * asyncSupported = true 表示开启异步支持
        */
        @WebServlet(name = "AsyncServlet",
            asyncSupported = true,
            urlPatterns = "/async")
        @Slf4j
        public class AsyncServlet extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws  ServletException, IOException {
        log.info("【doPost async Servlet 】");
        }
    
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long start = System.currentTimeMillis();
    
        //获取异步上下文
        AsyncContext asyncContext = request.startAsync();
    
        //使用java8的 CompletableFuture,将任务放到线程池中去执行
        CompletableFuture.runAsync(() -> {
            doSomeThing(asyncContext, asyncContext.getRequest(), asyncContext.getResponse());
        });
    
        long end = System.currentTimeMillis();
    
        log.info("【doGet async Servlet 耗时 {} 】", (end - start));
        }
    
        private void doSomeThing(AsyncContext asyncContext, ServletRequest request, ServletResponse response) {
    
        //执行业务代码
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //告诉异步上下文 结束了
    
        asyncContext.complete();
    
         }
        }
    

     浏览器访问

    http://localhost:8080/async
    

     可以看到日志,该Servlet仅仅只耗时 7毫秒,这样tomcat 调用这个Servlet得线程 又可以去处理其他请求,从而增加了吞吐量,
     这就是异步Servlet的作用

    Xnip20200225_171737.png

     4.解答问题:为什么使用异步Servlet? 同步Servlet阻塞了什么

     拿Tomcat服务器为例,当请求到达时候,Tomcat服务器会为每个请求创建一个线程,然后调用对应的Servlet的doGet或doPost方法,如果在该Servlet 的doPost 或者 doGet 方法中有业务耗时操作,则该线程会一直等待,直到业务逻辑处理完成才会把对应的 线程收回到Tomcat 重新接收请求

    而异步Servelt的目的就是 不用Tomcat的线程去等待,直接将其返回去接收其他请求,使用异步Servlet的支持 可以把耗时操作放入线程池中当执行完毕后 通知异步上下文去返回结果给前端 ,所以前端的反应其实看不出来什么效果,但是后台会有很大差异

     5.疑问

      5.1 使用SpringMVC 怎么使用异步

      看到这里肯定有人会问,现在谁还会去用Servlet去编程,都是用SpringMvc去编程了,当然SpringMvc早在3.2的版本中就已经对异步Servlet进行了支持,到现在已经提供了3中方式去实现异步

    • DeferredResult
    • Callable
    • CompletionStage/CompletableFuture

      详细使用教程后期会再写一篇,关于SpringMVC对异步Servlet的支持!

      5.2 有了SpringMVC 的异步支持 为什么还需要 Spring5提供的 WebFlux

      其实SpringMvc支持的异步已经能够满足我们的基本开发需要,那么为什么Spring还要引入 WebFlux 技术栈,
    就是 一种趋势,并发编程模型已经成趋势

     6.总结

    本篇主要讲解 如何使用 异步Servlet的处理请求,并且演示 同步Servlet和异步Servlet的区别,以及异步Servlet带来哪些好处。

    涉及的同步Servlet会带来的问题,并且简单聊了下SpringMVC里对异步Servlet的支持,等等。。
    后续会编写一篇关于SpringMVC对异步Servlet支持的详细教程,其实底层就是异步Servlet的使用 加油!!

    个人博客网站 https://www.askajohnny.com 欢迎来访问!
    本文由博客一文多发平台 OpenWrite 发布!

    相关文章

      网友评论

          本文标题:异步Servlet 特性

          本文链接:https://www.haomeiwen.com/subject/hzfvrhtx.html