Nginx 504 Gateway Time-out的两种最新解决方案

 更新时间:2022年08月17日 09:26:38   作者:fox_mt  
大家在访问网站的时候通常会遇到502错误、404错误等,很少会遇到504错误,但是在我们去访问大流量或者内容数据量较多的网站时,打开网页偶尔就会出现504 gateway time-out,这篇文章主要给大家介绍了关于Nginx 504 Gateway Time-out的两种解决方案,需要的朋友可以参考下

背景:

Nginx做反向代理,springboot为后端服务。

问题:

通过浏览器向后台发起请求够,由于后台处理时间长,出现504 Gateway Time-out,实际后台程序依然在执行。如何解决?

504从哪来:本文的场景下504是nginx返回的。

nginx配置中控制该超时时间的属性:

Syntax:proxy_read_timeout time;
Default:
proxy_read_timeout 60s;
Context:http, server, location

官方地址:Module ngx_http_proxy_module (nginx.org)

官方描述如下:Defines a timeout for reading a response from the proxied server. The timeout is set only between two successive read operations, not for the transmission of the whole response. If the proxied server does not transmit anything within this time, the connection is closed.

一个请求有三方参与:浏览器,nginx,后台服务器。

504的错误码是有nginx返回的。结合官网的解释,我们可以得出结论:

当nginx与后台的链接两次读取有效数据之间超过配置的时间时,就会产生504超时。nginx会主动关闭与后台服务器的链接。注意是两次成功读取的间隔,不是整个reponse的时间。

默认情况下proxy_read_timeout时60s。

如果你百度或google,通常解决方式有两种:提高后台处理效率增大proxy_read_timeout

增大方法很简单,proxy_read_timeout  [你期望的时间]。

But,后台效率提升总是有极限的。而proxy_read_timeout是固定值。总会有些正常业务场景,超过了设置的timeout值。

两种解决方案

本人解决的问题:上传excel文件后,由于文件大小无法预计,所以后台处理时间也无法预计。同时还要支持大文件的上传。上传后由后台解析处理。post请求,返回的是json。

一,关闭read-timout,可以实现,但是生产环境下你敢不设置超时时间么?所以不建议。

二,既然nginx只要从reponse成功读取数据两次的间隔在proxy_read_timeout设置的时间内,就不会超时。那么我们是不是可以通过持续的向response中写入数据来保证不超时呢。

答案是肯定的。

想通了这一点,实现就十分简单。

1,正常上传文件。

2,新建一个线程。持有response的引用,含有标志位,满足条件时循环执行,程序开始处理数据前,启动线程。

3,线程的功能只有一个,以固定间隔向response中写入数据。使nginx与后台链接不超时。

4,这里就需要注意,我的方法是返回json,同时要持续向response写入数据,所以我手动拼装json字符串。相当于在之前返回的json中增加一个属性,名称随意,我的叫pending,值随意,非空即可。我是用英文半角的句号" . "。

5,数据处理完后,回调线程的stop方法,终止线程中的循环。

注意:如有雷同纯属巧合。如果已经有大佬讲过这种解决方式,请艾特我,我立即删除本文。

保持线程代码如下:

#上下文代码
//获取鲜橙池executor,具体方式看个人。不会的直接百度,有很多
response.setContentType(ContentType.APPLICATION_JSON.getMimeType());
ResponseKeeper responseKeeper = new ResponseKeeper(response);
executorService.execute(responseKeeper);
#上下文代码
 
 
public class ResponseKeeper implements Runnable {
 
        /**
        * 循环标志:true时停止循环,终止线程
        */
        private boolean done = false;
        
        private HttpServletResponse response;
 
        public void stop(){
            done = true;
        }
 
        public ResponseKeeper(HttpServletResponse response) {
            this.response = response;
        }
 
        @Override
        public void run() {
            try {
                response.getWriter().write("{\"pending\":\"");
                while(!done){
                    response.getWriter().write(".");
                    response.getWriter().flush();
                    LOGGER.error("flush-{}", System.currentTimeMillis());
                    Thread.sleep(1000);
                }
                response.getWriter().write("\", \"status\": \"0\", \"msg\":\"success\"}");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

其他问题:

如果你遇到异常

IllegalStateException – if the getOutputStream method has already been called for this response object

那就说明你的程序中有地方调用过了,response.getOutputStream();

只需要与已有程序保持一致使用outputStream即可。

即将response.getWriter() 提换成 response.getOutputStream();

原因简单来讲就是这两个方法互斥。调用了一个就不能调用另一个。

总结

到此这篇关于Nginx 504 Gateway Time-out的两种解决方案的文章就介绍到这了,更多相关Nginx 504 Gateway Time-out内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • nginx修改上传文件大小限制的方法

    nginx修改上传文件大小限制的方法

    本篇文章主要介绍了nginx修改上传文件大小限制的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧。
    2016-12-12
  • 在nginx中设置三级域名的方法示例

    在nginx中设置三级域名的方法示例

    这篇文章主要介绍了在nginx中设置三级域名的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • nginx之Http代理和Websocket代理详解

    nginx之Http代理和Websocket代理详解

    本文介绍了在Ubuntu上安装和配置Nginx的步骤,包括启动、停止、重新加载配置、重新打开日志文件、查看进程等常用命令,还详细介绍了Nginx的静态代理和负载均衡功能,包括轮询、最少连接数、iphash和权重等策略
    2025-03-03
  • Nginx配置虚拟主机的三种方法

    Nginx配置虚拟主机的三种方法

    本文主要介绍了Nginx配置虚拟主机的三种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • nginx location语法使用介绍

    nginx location语法使用介绍

    Nginx 中的 Location 指令 是NginxHttpCoreModule中重要指令。Location 指令,是用来为匹配的 URI 进行配置,URI 即语法中的”/uri/”,可以是字符串或正则表达式。但如果要使用正则表达式,则必须指定前缀
    2015-01-01
  • nginx主动健康检查功能实现

    nginx主动健康检查功能实现

    nginx_upstream_check_module是一个Nginx的第三方模块,它可以实现 Nginx的主动健康检查功能,本文将介绍一个基于 Nginx 的第三方模块 nginx_upstream_check_module,它可以实现 Nginx 的主动健康检查功能,可以帮助我们更加有效地管理后端服务器,需要的朋友可以参考下
    2023-05-05
  • nginx之virtual host虚拟主机的配置实现

    nginx之virtual host虚拟主机的配置实现

    虚拟主机(vhost)技术允许一台物理服务器托管多个独立网站或应用,每个虚拟主机拥有独立的域名、配置文件等,实现资源隔离管理,Nginx服务器通过配置文件实现虚拟主机设置,感兴趣的可以了解一下
    2024-11-11
  • nginx反向代理配置去除前缀案例教程

    nginx反向代理配置去除前缀案例教程

    这篇文章主要介绍了nginx反向代理配置去除前缀案例教程,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • Nginx负载均衡配置实例

    Nginx负载均衡配置实例

    这篇文章主要介绍了Nginx负载均衡配置实例,随着互联网信息的爆炸性增长,负载均衡已经不再是一个很陌生的话题,顾名思义,负载均衡即是将负载分摊到不同的服务单元,既保证服务的可用性,又保证响应足够快,给用户很好的体验,需要的朋友可以参考下
    2023-07-07
  • nginx支持tcp转发的配置分享

    nginx支持tcp转发的配置分享

    本文给大家讲解的是使用nginx实现TCP转发的配置方法,非常的简单实用,并附上了所需模块的下载地址,有需要的小伙伴可以参考下
    2017-10-10

最新评论