结合HTTP 502-504 状态码学习Nginx配置

当网页无法正常访问,浏览器会及时通过数字代码(HTTP状态码)告知用户到底发生了什么,从而对问题开展排查并最终解决提供一定的帮助。

image-20210325080110087

这些数字代码就是HTTP状态码,HTTP状态码分为5大家族,其中2xx、4xx、5xx家族是大家比较熟悉的,比如200、404、502等。

本文将结合HTTP 502/504 状态码学习nginx两项关键参数配置proxy_read_timeout、proxy_connect_timeout,当参数生效后,触发特定条件将会出现502/504两个状态码。

一、状态码的含义

 

  • 502状态码

    502 Bad Gateway:作为网关或者代理工作的服务器尝试向上游服务器发起请求时,收到了无效的响应。

  • 504状态码

    504 Gateway Time-out:作为网关或者代理工作的服务器向上游服务器发起请求时,未能在一定的时间内从上游服务器收到响应。

两者的区别就是,一个是收到响应但无效,一个是超时并未能收到响应。

二、nginx配置项的含义

  • proxy_connect_timeout

    网关服务器向上游服务器建立连接的超时时间,默认60s。

  • proxy_read_timeout

    网关服务器向上游服务器读取数据的超时时间,也可以理解为后端服务器处理请求的超时时间,默认为60s。

三、环境准备服务器环境

服务器用途 IP地址 OS版本 安装软件
网关(代理)服务器 192.168.229.133 Ubuntu 18.04.3 LTS nginx/1.14.0
上游服务器(应用服务器) 192.168.229.134 Ubuntu 18.04.3 LTS Tomcat7/JDK7

应用环境

  1. 将hello.jsp放置到tomcat目录下的webapps/ROOT/根目录下
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String str = "hello world";
Thread.sleep(20000); //延时20秒
out.println(str);
%>
</body>
</html>
  1. 启动tomcat

四、实验过程

  1. nginx配置如下,并重载
server {
    listen 8081;
    server_name _;
    location / {
        proxy_connect_timeout 15s;
        proxy_read_timeout 15s;
        proxy_pass http://192.168.229.134:8080/hello.jsp;
    }
}

2.模拟502的发生

​ 第一步: 停掉上游服务器和关闭防火墙
​ 第二步: 测试

lvzhiqiang@DESKTOP-F60S61M:/mnt/c/Users/Q$ date;time curl -I http://192.168.229.133:8081/hello.jsp;
Wed Feb 19 09:39:22 CST 2020
HTTP/1.1 502 Bad Gateway
Server: nginx/1.14.0 (Ubuntu)
Date: Wed, 19 Feb 2020 01:39:22 GMT
Content-Type: text/html
Content-Length: 182
Connection: keep-alive

real 0m0.053s
user 0m0.016s
sys 0m0.031s

​ 第三步: 查看网关error日志

2020/02/19 09:39:22 [error] 22582#22582: *14 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.229.1, server: _, request: "HEAD /hello.jsp HTTP/1.1", upstream: "http://192.168.229.134:8080/hello.jsphello.jsp", host: "192.168.229.133:8081"

小结: 通过以上实验过程,可以看到502的出现和nginx两项配置(proxy_connect_timeout, proxy_read_timeout)并无关系,主要原因是上游服务器给回响应是无效的。

  1. 模拟2次 504的发生
  • 1) 第一次,模拟504的发生
    第一步: 上游服务器服务恢复和开启防火墙并拒绝端口访问
    第二步: 测试
lvzhiqiang@DESKTOP-F60S61M:/mnt/c/Users/Q$ date;time curl -I http://192.168.229.133:8081/hello.jsp;
Wed Feb 19 09:50:14 CST 2020
HTTP/1.1 504 Gateway Time-out
Server: nginx/1.14.0 (Ubuntu)
Date: Wed, 19 Feb 2020 01:50:29 GMT
Content-Type: text/html
Content-Length: 192
Connection: keep-alive

real 0m15.079s
user 0m0.000s
sys 0m0.031s

​ 第三步: 观察网关error日志

2020/02/19 09:50:29 [error] 22582#22582: *18 upstream timed out (110: Connection timed out) while connecting to upstream, client: 192.168.229.1, server: _, request: "HEAD /hello.jsp HTTP/1.1", upstream: "http://192.168.229.134:8080/hello.jsphello.jsp", host: "192.168.229.133:8081"

小结: 通过以上实验过程,可以看到504的出现和nginx配置(proxy_connect_timeout 15s;)有关系,主要原因是网关同上游服务器无法在指定时间(15s)内建立连接,导致超时发生。

  • 2)第二次,模拟504的发生
    第一步: 上游服务器服务恢复和关闭防火墙并允许访问
    第二步: 测试
lvzhiqiang@DESKTOP-F60S61M:/mnt/c/Users/Q$ date;time curl -I http://192.168.229.133:8081/;
Wed Feb 19 10:15:41 CST 2020
HTTP/1.1 504 Gateway Time-out
Server: nginx/1.14.0 (Ubuntu)
Date: Wed, 19 Feb 2020 02:15:55 GMT
Content-Type: text/html
Content-Length: 192
Connection: keep-alive

real 0m15.062s
user 0m0.016s
sys 0m0.016s

​ 第三步: 观察网关error日志

2020/02/19 10:15:55 [error] 24646#24646: *26 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 192.168.229.1, server: _, request: "HEAD / HTTP/1.1", upstream: "http://192.168.229.134:8080/hello.jsp", host: "192.168.229.133:8081"

小结: 通过以上实验过程,可以看到504的出现和nginx配置(proxy_read_timeout 15s;)有关系,主要原因是网关已经同上游服务器建立连接,但是在等待读取上游给回的数据的时候(上游服务器代码加入一个sleep,延迟25s给回数据)发生超时。

总结: 通过以上实验过程,一方面增进对nginx参数的意义理解, 另一方面透过数字代码深入了解WEB服务的世界到底发生了什么!

猜你喜欢

转载自blog.51cto.com/4073279/2671312