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.异步请求是通过容器线程和程序线程的分配来提高效率。

  • 相关阅读:
    什么是ORM
    ORM优缺点
    Azure 中快速搭建 FTPS 服务
    连接到 Azure 上的 SQL Server 虚拟机(经典部署)
    在 Azure 虚拟机中配置 Always On 可用性组(经典)
    SQL Server 2014 虚拟机的自动备份 (Resource Manager)
    Azure 虚拟机上的 SQL Server 常见问题
    排查在 Azure 中新建 Windows 虚拟机时遇到的经典部署问题
    上传通用化 VHD 并使用它在 Azure 中创建新 VM
    排查在 Azure 中新建 Windows VM 时遇到的部署问题
  • 原文地址:https://www.cnblogs.com/shadoll/p/14447854.html
Copyright © 2011-2022 走看看