zoukankan      html  css  js  c++  java
  • SpringBoot中异步请求的使用

    一.前言

      正常的http请求是由一个线程从头到尾来处理,当如果有请求耗时过长,而我们容器的线程数量是有限的,但所有线程都在使用,就会造成新的请求无法进行。

      异步请求可以实现当http请求进入到程序,可以先释放容器的线程,由程序内部的线程进行处理,等处理完成后,再调回容器的线程来返回请求结果。这就可以在一定程度上提高系统的吞吐量。

    二.实现

      1.使用Servlet方法来实现

    @RequestMapping(value = "/importData", method = RequestMethod.POST)
    public void importData(HttpServletRequest request) {
        AsyncContext asyncContext = request.startAsync();
        //设置监听器:可设置其开始、完成、异常、超时等事件的回调处理
        asyncContext.addListener(new AsyncListener() {
          @Override
            public void onTimeout(AsyncEvent event) throws IOException {
              System.out.println("超时了...");
              //做一些超时后的相关操作...
            }
            @Override
            public void onStartAsync(AsyncEvent event) throws IOException {
              System.out.println("线程开始");
            }
            @Override
            public void onError(AsyncEvent event) throws IOException {
              System.out.println("发生错误:"+event.getThrowable());
            }
            @Override
            public void onComplete(AsyncEvent event) throws IOException {
              System.out.println("执行完成");
              //这里可以做一些清理资源的操作...
            }
        });
        //设置超时时间
        asyncContext.setTimeout(3000000);//5分钟
        asyncContext.start(() -> {
            Result rm = new Result();
            try {
                System.out.println("内部线程:" + Thread.currentThread().getName());
                asyncContext.getResponse().setCharacterEncoding("utf-8");
                asyncContext.getResponse().setContentType("text/html;charset=UTF-8");
                asyncContext.getResponse().getWriter().println("返回成功");
            } catch (Exception e) {
                System.out.println("异常:" + e);
            }
            //异步请求完成通知
            //此时整个请求才完成
            asyncContext.complete();
        });
        //此时之类 request的线程连接已经释放了
        System.out.println("主线程:" + Thread.currentThread().getName());
    }

       2.在SpringBoot中可以使用Callable、DeferredResult、WebAysncTask。这里只举Callable的代码例子。

    @RequestMapping("/callable")
    public Callable<String> callable() {
        log.info("外部线程:" + Thread.currentThread().getName());
        return new Callable<String>() {
    
            @Override
            public String call() throws Exception {
                log.info("内部线程:" + Thread.currentThread().getName());
                return "callable!";
            }
        };
    }

    三.总结

      1.异步请求可以有效提供系统的吞吐量。

      2.异步请求是通过容器线程和程序线程的分配来提高效率。

  • 相关阅读:
    2020学习 04 python 爬取某政府网站信件
    2020学习03
    2020学习02
    阅读笔记--《一线架构师实践指南》--Pre-architecture阶段
    重构“信息领域热词分析”,实现六种质量属性战术
    pycharm错误:Error updating package list: connect timed out解决
    python连接mysql数据库——编码问题
    阅读笔记--《大型网站技术架构》—02架构
    python查询MySQL数据库的表以及所有字段
    python连接mysql数据库——版本问题
  • 原文地址:https://www.cnblogs.com/shadoll/p/14447854.html
Copyright © 2011-2022 走看看