nginx设置连接超时解决504 gateway timeout

清疚 2022-03-14 11:42 3946阅读 0赞

nginx做反向代理,默认请求是有一个60秒的超时,如果http请求超过了60秒,再返回,连接就会被nginx中断,前端就会得到504的错误:gateway time-out。

如下,我们可以通过实验验证,默认的超时时间是60秒:

1、我们在页面上,做一个耗时的请求,后台线程sleep(70*1000),模拟这个耗时操作,让这个耗时操作撑过60秒。默认情况下,不使用nginx做反向代理,请求会在70秒后,正常返回。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZlaW5pZmk_size_16_color_FFFFFF_t_70

2、我们使用nginx反向代理,将http://127.0.0.1/struts2hack的请求,代理到http://127.0.0.1:8080上,就是默认正常的请求服务上。

20190304150717957.png

接着,我们点击页面的测试按钮,我们等待1分钟,会出现如下图所示的结果:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZlaW5pZmk_size_16_color_FFFFFF_t_70 1

请求在一分钟后,即60秒时连接被断开,返回504。这个结果符合预期,说明了nginx默认超时时间是60s,超过60s,连接会被断开,为此,我们需要解决这个问题,就需要设置nginx超时时间了,这里我们将超时时间设置为3600,就是一个小时,这个值可以灵活设置,就是不让他在默认60秒断开链接。

20190304151040236.png

location ~ /struts2hack {
proxy_pass http://127.0.0.1:8080;
proxy_read_timeout 3600;
}

设置之后,我们再次点击页面的测试按钮,我们得到的结果就和最初一样了,经过70秒,服务端返回了数据,请求完成。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZlaW5pZmk_size_16_color_FFFFFF_t_70 2

前端页面代码:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"%>
  2. <!DOCTYPE html>
  3. <html>
  4. <head>
  5. <meta charset="UTF-8"/>
  6. <link rel="stylesheet" type="text/css" href="css/base.css"/>
  7. <script type="text/javascript" src="js/libs/jquery-1.12.4.min.js"></script>
  8. </head>
  9. <body>
  10. <h2>nginx timeout!</h2>
  11. <div class="box">
  12. <input type="button" value="timeout测试" id="btn-test"/>
  13. </div>
  14. <div class="box">
  15. 开始时间:<input type="text" name="start" id="start">
  16. </div>
  17. <div class="box">
  18. 结束时间:<input type="text" name="end" id="end">
  19. </div>
  20. <div class="box">
  21. 返回数据:<input type="text" name="data" id="data">
  22. </div>
  23. </body>
  24. <script type="text/javascript">
  25. $(function(){
  26. $("#btn-test").click(function(e){
  27. $.ajax({
  28. url:"timeout!test.action",
  29. type:"get",
  30. beforeSend:function(){
  31. $("#start").val(new Date());
  32. },
  33. success:function(data){
  34. $("#data").val(data.message);
  35. $("#end").val(new Date());
  36. },
  37. error:function(XMLHttpRequest,textStatus,errorThrown){
  38. $("#end").val(new Date());
  39. $("#data").val("timeout");
  40. }
  41. });
  42. });
  43. });
  44. </script>
  45. </html>

后端模拟70秒的耗时请求:

  1. package com.xxx.action;
  2. import java.io.PrintWriter;
  3. import javax.servlet.http.HttpServletResponse;
  4. import org.apache.struts2.ServletActionContext;
  5. public class TimeoutAction {
  6. public String test() {
  7. HttpServletResponse response = ServletActionContext.getResponse();
  8. response.setContentType("application/json;charset=UTF-8");
  9. PrintWriter out = null;
  10. try {
  11. Thread.sleep(70*1000);
  12. out = response.getWriter();
  13. String content = "{\"code\":200,\"message\":\"ok\"}";
  14. out.write(content);
  15. } catch (Exception e) {
  16. e.printStackTrace();
  17. }finally {
  18. if(out!=null) {
  19. out.close();
  20. }
  21. }
  22. return null;
  23. }
  24. }

最初,我以为使用了jQuery的ajax请求超时,那么需要对ajax做一个超时设置,给参数timeout 设置上一个值,但是最终,发现问题不在ajax超时上,因为默认ajax是不会有超时的,就是永不超时,timeout:0就是默认值。这些可以在JQuery源码中找到。

发表评论

表情:
评论列表 (有 0 条评论,3946人围观)

还没有评论,来说两句吧...

相关阅读

    相关 nginx 解决504超时问题

    问题发现 最近在做文件解析服务的压测,发现jmeter 基本有所有的错误反馈都是504,大概有1%左右的请求报504。由于文件解析服务耗时相对比较长,所以导致等待超时。

    相关 nginx + tomcat 504 gateway timeout

    出现问题时我这里的现象: web服务器:nginx  应用服务器:tomcat  开发语言:java 客户端只请求了一次,发现后台多个应用服务器的点依次接收到了请求,一