前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一边制造,一边讲解http状态码502|504|499|500

一边制造,一边讲解http状态码502|504|499|500

作者头像
后端技术探索
发布2018-12-18 16:46:05
8.5K0
发布2018-12-18 16:46:05
举报
文章被收录于专栏:后端技术探索后端技术探索

Status Code 499、500、502、504也是后端Http服务经常返回的状态码,试想一下,对于每个状态码,如果你能通过一些修改或配置来人为复现它,是不是会更利于你去掌握它呢?本文就是通过制造它们的方式来学习它们。

502,504在超时的场景下会比较像,经常有人不能区分它们。499产生的原因也常常会和504会有内在的关联,你都了解吗?本文不光制造它们,而且会循序渐进,在对比之中制造它们。

复现环境说明

系统环境和软件环境为:Linux,Nginx,php-fpm

再来介绍一下本文复现会用到的Nginxphp-fpm的几个配置。

代码语言:javascript
复制
#nginx超时相关配置:

fastcgi_connect_timeout 5; # nginx连接fastcgi的超时时间

fastcgi_send_timeout 10; #nginx往fastcgi发送参数的超时时间

fastcgi_read_timeout 10; #nginx从fastcig获取数据的超时时间

php-fpm配置:

代码语言:javascript
复制
; The timeout for serving a single request after which the worker process will

; be killed. This option should be used when the 'max_execution_time' ini option

; does not stop script execution for some reason. A value of '0' means 'off'.

; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)

; Default Value: 0

; 翻译过来就是指一次请求的最长执行时间

request_terminate_timeout = 30s

所有复现场景都是在nginx根目录下创建一个hello.php文件,然后通过访问http://127.0.0.1/hello.php 来查看http响应codehello.php代码如下:

代码语言:javascript
复制
<?php

sleep(7);  // 通过调整sleep秒数,来达成不同的复现

echo 'hello world';

?>

下面来逐一复现这些状态码的产生场景。

502

定义

502Bad Gateway,网关错误,它往往表示网关从上游服务器中接收到的响应是无效的。

先来了解一下网关是什么含义,从宏观定义上来说只要连接两个不同的网络的设备都可以叫网关,其实具体到应用层Http请求这一领域,网关就是指是转发其他服务器通信数据的服务器,对于本文的复现环境而言,当客户端请求数据到达nginxnginx负责把请求转交给fastcgi(即php-fpm)进行处理,那么在这个场景中Nginx就是网关。

502并不是指网关本身出了问题,而是从上游接收响应出了问题,比如由于上游服务自身超时导致不能产生响应数据,或者上游不按照协议约定来返回数据导致网关不能正常解析。

复现路径1

关闭php-fpm进程,返回502

这个比较容易理解,参照上面的定义,因为php-fpm进程关闭,nginx连接不上php-fpm,即nginx的上层无响应数据导致的网关错误。

nginx 错误日志如下:

代码语言:javascript
复制
connect() to unix:/home/work/server/php-cgi.sock failed (2: No such file or directory) while connecting to upstream
复现路径2

启动php-fpm进程,修改php-fpm.confrequest_terminate_timeoutphp代码的sleep时间来复现。

php代码:

代码语言:javascript
复制
<?php

sleep(7); 

echo 'hello world';

?>

php-fpm.conf配置:

代码语言:javascript
复制
request_terminate_timeout=5

nginx配置:

代码语言:javascript
复制
fastcgi_read_timeout 10;

php-fpm.conf设置的最大执行时间是5s,但是php脚本需要的执行时间大于7s,所以php-fpm进程执行5s时就回退出,此时php脚本没有正常执行完,返回给网关Nginx的数据为空,于是导致502

php-fpm错误日志如下:

代码语言:javascript
复制
script '/home/work/webroot/hello.php' (request: "GET /hello.php") execution timed out (5.161544 sec), terminating

nginx错误日志如下:

代码语言:javascript
复制
recv() failed (104: Connection reset by peer) while reading response header from upstream

504

定义

504Gateway Timeout,网关超时。

它表示网关没有从上游及时获取响应数据。注意它和502在超时场景下的区别,502是指上游php-fpm因为超过自身允许的执行时间而不能正常生成响应数据,而504是指在php-fpm还未执行完成的某一时刻,由于超过了nginx自身的超时时间,nginx则以为上游php-fpm没有按照设置时间返回响应数据就会返回504, 此时对于php-fpm而言还会继续执行下去,直到执行完成。

复现路径

php代码

代码语言:javascript
复制
<?php

sleep(7); 

echo 'hello world';

error_log("hello", 3, "/tmp/hello.log");

?>

php-fpm.conf配置:

代码语言:javascript
复制
request_terminate_timeout=30

nginx配置:

代码语言:javascript
复制
fastcgi_read_timeout 5;

hello.php脚本执行时间需要7s,远小于php-fpm的一次请求的最大请求时间30s,所以php脚本可以正常完成执行,这个可以查看/tmp/hello.log文件内容来得到证明。

由于nginxphp-fpm读取数据的超时时间为5s,所以在5s的时科,nginx还未从php-fpm获取到响应数据,于是返回504

nginx错误日志如下:

代码语言:javascript
复制
upstream timed out (110: Connection timed out) while reading response header from upstream

499

定义

499, Client Closed Request, 客户端主动断开连接。 是指一次http请求在客户端指定的时间内没有返回响应,此时,客户端会主动断开连接,此时表象为客户端无响应返回,而nginx的日志中会status code499

此状态码在浏览器请求时几乎不可见,因为浏览器默认的超时时间会很长。多见于服务之间的调用,在业务架构中常常会分层设计,拆分为不同的子系统或者微服务,这样系统之间就会常常通过http方式来请求,并且会设置每次请求的超时时间,当请求在请求时间内所调用的上游服务无返回,则会主动关闭连接,上游服务日志中会记录一条499

复现路径

我们用上面504复现时相同的代码和配置。

php代码

代码语言:javascript
复制
<?php

sleep(7); 

echo 'hello world';

error_log("hello", 3, "/tmp/hello.log");

?>

php-fpm.conf配置:

代码语言:javascript
复制
request_terminate_timeout=30

nginx配置:

代码语言:javascript
复制
fastcgi_read_timeout 5;

我们在linux终端使用curl命令来请求,-m 表示超时时间,单位为秒

代码语言:javascript
复制
curl -i -m 3 http://127.0.0.1/hello.php 

返回为:

代码语言:javascript
复制
curl: (28) Operation timed out after 3004 milliseconds with 0 bytes received

nginxaccess日志的code499,如下:

代码语言:javascript
复制
"HEAD /hello.php HTTP/1.1" 499 0 

500

定义

500, Internal Server Error , 服务器内部错误,服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。

日常开发中500错误几乎都是由于php脚本语法出现错误导致php-fpm无法正常执行。

复现路径

php代码:

代码语言:javascript
复制
<?php
echo 'hello '
echo ' world';
?>

由于php代码语法错误,php-fpm执行失败,然后告诉nginx这一结果,nginx则返回500

php错误日志:

代码语言:javascript
复制
PHP Parse error:  syntax error, unexpected 'echo' (T_ECHO), expecting ',' or ';' in /home/work/webroot/hello.php on line 3

总结

  • 499是由于超过客户端设置的请求超时时间,客户端主动关闭连接,服务器code499
  • 500多是由于代码语法错误,导致CGI执行错误并且会把错误结果通知服务器,服务器则报500
  • 502是由于CGI由于在自身的执行时间要求内无法按时完成,则无法返回给服务器正常响应,此时服务器会返回502
  • 504CGI在服务器设置的超时时间内无法按时返回响应,服务器则返回504
  • 499,502,504都会因为超时而产生,区别是超时超了谁的时,499是超了客户端本身的连接时间,502是超了CGI的执行时间,504是超了服务器本身的最大允许读取时间。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-11-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 nginx 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 复现环境说明
  • 502
    • 定义
      • 复现路径1
        • 复现路径2
        • 504
          • 定义
            • 复现路径
            • 499
              • 定义
                • 复现路径
                • 500
                  • 定义
                    • 复现路径
                    • 总结
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档