当前位置:主页 > java教程 > springboot实现异步响应请求

springboot如何实现异步响应请求(前端请求超时的问题解决)

发布:2023-04-21 16:40:01 59


给大家整理一篇相关的编程文章,网友丁雨泽根据主题投稿了本篇教程内容,涉及到springboot、异步响应请求、springboot异步请求处理、springboot异步接口响应、springboot实现异步响应请求相关内容,已被123网友关注,内容中涉及的知识点可以在下方直接下载获取。

springboot实现异步响应请求

问题

实际场景中会遇到请求业务处理流程耗时较长,比如长查询,远程调用等,主线程会被一直占用会影响其他请求的响应,导致服务端性能下降。同时,前端向服务端发送请求后等待响应的超时时间比较短(一般20s或30s),而我们实际业务执行可能超过1分钟。所以以下需要解决此问题。

解决方案

解决的方案分为以下两步骤

1.服务端异步处理

你需要将请求接口进行一些简单的改进。将返回值类型变更为Callable<T>类型,其中T可以为任意类型比如String或你原有的自定义类型。以下的new Callable方法,会新建一个线程,用于执行业务逻辑并在得到结果后自动返回给前端。而主线程无需等待。

    @RequestMapping(value = "/GetMonthCdateRpt", method = RequestMethod.POST)
    @ResponseBody
    public Callable<String> GetMonthCdateRpt(@RequestBody HashMap<String, Object> map) {
        logger.info("主线程开始");
        Callable<String> result = new Callable<String>() {
            @Override
            public String call() throws Exception {
                logger.info("副线程开始");
                /*这里沉睡1分钟,表示处理耗时业务执行*/
                Thread.sleep(60000);
                logger.info("副线程返回");
                return "success";
            }
        };
        logger.info("主线程返回");
        return result;
    }

2.设置响应时间

改进完接口方法后,你需要新建一个WebMvcConfigurer的实现类,名字可以为WebAppConfigurer.java实现异步处理的支持,如果你已存在其他WebMvcConfigurer的类,则可以把代码追加进去。代码内容如下:

@Configuration
public class WebAppConfigurer implements WebMvcConfigurer {
 
    //异步处理支持
    @Override
    public void configureAsyncSupport(final AsyncSupportConfigurer configurer) {
        configurer.setDefaultTimeout(120 * 1000L);//设置响应时间 120s
        configurer.registerCallableInterceptors(timeoutInterceptor());
        configurer.setTaskExecutor(threadPoolTaskExecutor());
    }
    @Bean
    public TimeoutCallableProcessingInterceptor timeoutInterceptor() {
        return new TimeoutCallableProcessingInterceptor();
    }
    @Bean
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor t = new ThreadPoolTaskExecutor();
        t.setCorePoolSize(10);
        t.setMaxPoolSize(100);
        t.setQueueCapacity(20);
        t.setThreadNamePrefix("WYF-Thread-");
        return t;
    }
}

执行完以上两步骤后,重新运行服务,调用接口可以异步返回结果,前端可以最大等待的响应时间为上面设置的120s。

问题已解决。

需要避免踩到的坑

如果你按上文操作后,还是会出现超时情况,有可能是你用到了以下几种软件,需要对应设置一下。

1.关于dubbo中的设置

如果你使用的了dubbo这样的Jave RPC框架,你除了以上设置后,还需要在application-*.yml配置消费端的默认的响应超时时长。

dubbo:
  application:
    name: myweb
 
  consumer:
    timeout: 120000 #默认超时时间120s

同时注意在dubbo的*consume-client.xml服务注册中,如果单个服务也设置了timeout会以各自服务配置的超时时长为准。如下的timeout是20秒,需要修改或直接删掉此timeout的设置。

    <dubbo:reference id="reportUserInfoService"
                     interface="com.zh.fee.service.UserInfoService" timeout="20000"
                     retries="0" check="false"/>

2.关于tomcat的设置

上文中是springboot开发环境,使用了内置的tomcat。而在实际生产环境中一般用的是外置tomcat来部署(便于后续发布更新),需要在tomcat的配置文件server.xml中设置超时时间(默认20秒以下设置为120秒)。

    <Connector port="8811" protocol="HTTP/1.1"
               connectionTimeout="120000"
               redirectPort="8443" />

3.关于Nginx的设置

如果服务端使用到Nginx做了反向代理转发请求,就需要在Nginx的配置文件nginx.conf中设置超时时间,否则会返回“java.io.IOException: 你的主机中的软件中止了一个已建立的连接”这样的异常提示。

未设置时Nginx响应时间默认60秒,这里我将http头部的keepalive_timeout 、client_header_timeout 、client_body_timeout 、send_timeout 、以及server代码块中的proxy_read_timeout 均配置为120秒。

http {
    include       mime.types;
    default_type  application/octet-stream;
    client_max_body_size 100m;
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
 
    #access_log  logs/access.log  main;
 
    sendfile        on;
    #tcp_nopush     on;
 
    keepalive_timeout  120; #连接超时时间,服务器将会在这个时间后关闭连接
    send_timeout 120;    #发送超时时间
    client_header_timeout 120;    #请求头的超时时间
    client_body_timeout 120;    #请求体的读超时时间
    #gzip  on;
 
.....
 
    #业务系统的配置
    server {
        listen       9092;
        server_name  localhost;
	
    	location / {
             proxy_pass http://127.0.0.1:8811/mywebsev/;
	         proxy_read_timeout 120;  # 等候后端服务器响应时间 秒
            }
    }
}

保存完记得重启Nginx。

以上完毕。

总结

到此这篇关于springboot如何实现异步响应请求(前端请求超时的问题解决)的文章就介绍到这了,更多相关springboot实现异步响应请求内容请搜索码农之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持码农之家!


参考资料

相关文章

  • springboot使用mybatis开启事务回滚

    发布:2023-04-14

    本文主要介绍了springboot使用mybatis开启事务回滚,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧


  • 详解SpringBoot中的统一功能处理的实现

    发布:2023-04-22

    这篇文章主要为大家详细介绍了SpringBoot如何实现统一功能处理,文中的示例代码讲解详细,对我们学习或工作有一定借鉴价值,需要的可以参考一下


  • spring boot 集成 shiro 自定义密码验证 自定义freemarker标签根据权限渲染不同页面(推荐

    发布:2022-11-03

    为网友们分享了关于spring boot的教程,这篇文章主要介绍了spring-boot 集成 shiro 自定义密码验证 自定义freemarker标签根据权限渲染不同页面,需要的朋友可以参考下


  • SpringBoot中多环境配置和@Profile注解示例详解

    发布:2023-04-25

    这篇文章主要介绍了SpringBoot中多环境配置和@Profile注解,本文结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下


  • 详解SpringBoot是如何保证接口安全的

    发布:2023-04-16

    对于互联网来说,只要你系统的接口会暴露在外网,就避免不了接口安全问题。 如果你的接口在外网裸奔,只要让黑客知道接口的地址和参数就可以调用,那简直就是灾难。这篇文章主要介绍了SpringBoot保证接口安全的方法,需要的可以参考一下


  • SpringBoot使用自定义json解析器的方法实例

    发布:2020-04-29

    本篇文章主要介绍了SpringBoot使用自定义json解析器的使用方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧


  • 优化SpringBoot程序启动速度的实现

    发布:2023-03-10

    本文主要介绍了优化SpringBoot程序启动速度的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧


  • springboot整合kaptcha生成验证码功能

    springboot整合kaptcha生成验证码功能

    发布:2022-09-14

    给大家整理一篇关于springboot的教程,这篇文章主要介绍了springboot整合kaptcha生成验证码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下


网友讨论