关于http:HTTP状态码499502503504原理及复现

46次阅读

共计 3244 个字符,预计需要花费 9 分钟才能阅读完成。

502,504 在超时场景下很容易被混同,辨别起来有肯定难度;
499 产生的起因往往也会和 504 会有外在关联。

注:本文为间断测试,所以批改 nginx 或 php-fpm 配置后,记得重启

根本环境(LNMP):

nginx 配置
fastcgi_connect_timeout 5; # nginx 连贯 fastcgi 的超时工夫
fastcgi_send_timeout 10; #nginx 往 fastcgi 发送参数的超时工夫
fastcgi_read_timeout 10; #nginx 从 fastcig 获取数据的超时工夫
php-fpm 配置
request_terminate_timeout = 30 ; 一次申请的最长执行工夫
PHP 脚本:
nginx 的 webroot 创立 codetest.php 文件,通过拜访 localhost/codetest.php 复现 http 响应 code;

499 复现

php-fpm.conf:
request_terminate_timeout=30
nginx:
fastcgi_read_timeout 5;
代码:
sleep(15);
echo ‘hello world’;

499 报错信息:Client Closed Request;即 客户端被动断开连接。

指一次 http 申请在客户端指定的工夫内没有返回响应,此时,客户端会被动断开连接,此时表象为客户端无响应返回;
此状态码在浏览器申请时简直不可见,因为浏览器默认超时工夫很长
多见于业务架构中的服务模块之间的调用。

复现路径:

在 linux 终端应用 curl 命令申请,-m 示意超时工夫,单位秒
curl -i -m 3 http://127.0.0.1/codetest.php
返回:
Operation timed out after 3004 milliseconds with 0 bytes received
此时,nginx 的 access_log 会呈现如下信息:
"HEAD /codetest.php HTTP/1.1" 499

502 复现

502,Bad Gateway,网关谬误,它往往示意网关从上游服务器中接管到的响应是有效的。

先来理解一下网关是什么含意

从宏观定义上来说只有是连贯两个不同网络设备的都能够叫网关,具体到 Http 申请这里,网关就是指是转发其余服务器通信数据的服务器,于本文而言,Nginx 就是网关。

502 并不是指网关自身出了问题,而是从上游接管响应出了问题,比方因为上游服务本身超时导致不能产生响应数据,或者上游不依照协定约定来返回数据导致网关不能失常解析。

复现门路 -1

敞开 php-fpm 过程,返回 502。
这个比拟容易了解,参照下面的定义,因为 php-fpm 过程敞开,nginx 连贯不上 php-fpm,即 nginx 不能收从下层接管到响应数据。

nginx 谬误日志相似如下内容:
connect() to unix:xxxx/php-cgi.sock failed (2: No such file or directory) while connecting to upstream

复现门路 -2

启动 php-fpm 过程,批改 php-fpm.conf 的 request_terminate_timeout 和 php 代码的 sleep 工夫来复现。
php 代码:
`sleep(15);
echo ‘hello world’;`
php-fpm.conf
request_terminate_timeout=5
nginx
fastcgi_read_timeout 10;
php-fpm.conf 设置的最大执行工夫是 5s,然而 php 脚本须要的执行工夫大于 15s,所以 php-fpm 过程执行 5s 时就回退出,此时 php 脚本没有失常执行实现,所以返回给网关 Nginx 的数据异样,于是导致 502。

php-fpm 谬误日志如下:
script ‘/webroot/codetest.php’ (request: “GET /codetest.php”) execution timed out (5.161544 sec), terminating
nginx 谬误日志
recv() failed (104: Connection reset by peer) while reading response header from upstream

503 复现

503,Service Unavailable,服务不可用;
如果你搜寻 503,大部分文章会通知你,这是服务器在保护或者过载,高并发下个别会呈现此状态值;

严格来说,除非是 DDoS 攻打之类间接导致服务器宕机了,否则高并发并不会间接触发 503,而是触发 502 才对;

参考下面的 502 复现场景,高并发最间接的影响是,没有足够的 PHP 过程来解决客户端申请,而个别 NGINX 承载的连接数是远远大于 PHP-fpm 的,所以问题大概率不是 NGINX 这里;

如果想复现 NGINX-503 谬误,能够通过设置 NGINX 的 连接数限度来复现;
具体路径是:设置 limit_conn
在 NGINX 配置文件中的 http 模块增加如下:
limit_conn_zone $binary_remote_addr zone=per_ip:10m;
意思是:对用户 IP 进行并发计数,将计数内存区命名为 per_ip,设置计数内存区大小为 10MB;
之后在 http 模块下的 server 模块增加相似如下限度:

## 残缺配置 demo
http{
    limit_conn_zone $binary_remote_addr zone=per_ip:10m; 
    server {
        location /{
            limit_conn per_ip 3; # 限度用户 ip 的并发连接数为 3
            root……
            index……
        }
    }
}

最初开启多线程,或者应用 ab 等压测工具,将并发数调到大于 3(因为下面的 demo 设置为最大连接数 3);
而后去拜访接口codetest.php,即可复现 503 谬误。

因而,常见的 503 大多是 NGINX 开启了并发连接数限度导致,比方,你的接口被爬虫抓取;
如果是通过在 PHP 层通过 redis 限度拜访频次,则可抛出自定义的谬误,比方,401 等;
所以高并发呈现 503,并不是相对的,须要辩证的去对待,这里只是列举了一种可能。

504 复现

504,Gateway Timeout,网关超时。

它示意网关没有从上游及时获取响应数据。留神它和 502 在超时场景下的区别,502 是指上游 php-fpm 因为超过本身容许的执行工夫而不能失常生成响应数据,而 504 是指在 php-fpm 还未执行实现的某一时刻,因为超过了 nginx 本身的超时工夫,nginx 则认为上游 php-fpm 没有依照设置工夫返回响应数据就会返回 504,此时对于 php-fpm 而言还会继续执行上来,直到执行实现。

复现门路
代码:
`sleep(15);
echo ‘hello world’;`
php-fpm.conf
request_terminate_timeout=30
nginx
fastcgi_read_timeout 5;
codetest.php 脚本执行工夫须要 15s,小于 php-fpm 设置的一次申请的超时工夫 30s,所以 php 脚本可失常实现;
但 nginx 从 php-fpm 读取数据的超时工夫为 5s,所以在 5s 时,PHP 未执行实现,但 nginx 的超时等待时间到了,于是返回 504。

nginx 谬误日志
upstream timed out (110: Connection timed out) while reading response header from upstream

面试 Summary:

  • 499 是因为超过客户端设置的申请超时工夫,客户端被动敞开连贯;
  • 502 是因为 php-fpm 在本身的执行工夫要求内无奈按时实现,无奈返给 NGINX 失常的响应值;
  • 504 是 php-fpm 在 NGINX 设置的超时工夫内无奈按时实现;
  • 503 大多由 NGINX 开启了连接数限度后的高并发起因产生;

499,502,504,都是因超时而产生,区别在于,谁超了谁的时。
499 是超了客户端自身的连接时间;
502 是超了 php-fpm 的执行工夫;
504 是超了 NGINX 容许的最大读取工夫。

正文完
 0