http错误码原理及复现 - 499,500,502,504

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

下面所有复现的场景,修改nginx或者php-fpm的配置后,记得要重新启动。

环境介绍

  • 系统环境和软件环境为:Linux,Nginx,php-fpm
    • nginx 配置
    fastcgi_connect_timeout 5; # nginx连接fastcgi的超时时间
    fastcgi_send_timeout 10; #nginx往fastcgi发送参数的超时时间
    fastcgi_read_timeout 10; #nginx从fastcig获取数据的超时时间
    
    • php-fpm配置
    ; 一次请求的最长执行时间
    request_terminate_timeout = 30s
    
    所有复现场景都是在nginx根目录下创建一个hello.php文件,然后通过访问http://127.0.0.1/hello.php 来查看http响应code,hello.php代码如下:
    <?php
    
       sleep(7);  // 通过调整sleep秒数,来达成不同的复现
       echo 'hello world';
    ?>
    

499

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

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

  • 复现路径
    • php-fpm.conf
      request_terminate_timeout=30
    • nginx
      fastcgi_read_timeout 5;
    • php
    <?php
        sleep(7); 
        echo 'hello world';
        error_log("hello", 3, "/tmp/hello.log");
    ?>
    
    我们在linux终端使用curl命令来请求,-m 表示超时时间,单位为秒
    curl -i -m 3 http://127.0.0.1/hello.php
    返回:
    curl: (28) Operation timed out after 3004 milliseconds with 0 bytes received
    nginx的access日志的code为499,如下:
    "HEAD /hello.php HTTP/1.1" 499 0

500

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

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

  • 复现路径

    • php
    <?php
    
        echo 'hello world'
    ?>
    

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

    php错误日志:
    PHP Parse error: syntax error, unexpected 'echo' (T_ECHO), expecting ',' or ';' in hello.php on line 2

502

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

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

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

  • 复现路径1
    关闭php-fpm进程,返回502。
    这个比较容易理解,参照上面的定义,因为php-fpm进程关闭,nginx连接不上php-fpm,即nginx不能收从上层接收到响应数据。

    nginx 错误日志如下:
    connect() to unix:/tmp/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

    <?php
    
      sleep(7); 
      echo 'hello world';
    ?>
    

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

    php-fpm错误日志如下:
    script '/webroot/hello.php' (request: "GET /hello.php") execution timed out (5.161544 sec), terminating
    nginx错误日志
    recv() failed (104: Connection reset by peer) while reading response header from upstream

504

504,Gateway Timeout,网关超时。

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

  • 复现路径
    php

    <?php
    
      sleep(7); 
      echo 'hello world';
      error_log("hello", 3, "/tmp/hello.log");
    ?>
    

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

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

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

总结

499是由于超过客户端设置的请求超时时间,客户端主动关闭连接,服务器code为499。

500多是由于代码语法错误,导致CGI执行错误并且会把错误结果通知服务器,服务器则报500。

502是由于CGI由于在自身的执行时间要求内无法按时完成,则无法返回给服务器正常响应,此时服务器会返回502。

504是CGI在服务器设置的超时时间内无法按时返回响应,服务器则返回504。

499,502,504都会因为超时而产生,区别是超时超了谁的时,499是超了客户端本身的连接时间,502是超了CGI的执行时间,504是超了服务器本身的最大允许读取时间。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352

推荐阅读更多精彩内容