有学有练才叫学习:学而不思则罔,思而不学则殆:学而不习,纸上谈兵,习而不进,画地为牢!

nginx 408 (nginx httpstatus 408)已解决

nginx 炮渣日记 4周前 (11-11) 23次浏览 已收录 0个评论 扫描二维码

常见 http 错误码

以下是服务器巡检时比较常见的 http 错误码,后端的 web 容器为 jetty

  • 400 Bad Request
    • 多半是有必须的参数没有传
  • 499 client has closed connection
    • 在 nginx 返回结果之前,客户端断开了连接,此时 nginx 还在等待 web 容器的结果
  • 502 Bad Gateway
    • web 容器挂了或者没有启动
  • 504 Gateway Timeout
    • nginx 等待 web 容器超时了,可以修改nginx 配置来增加超时时间: proxy_read_timeout 3m;

408 Request Timeout

408 这个错误码很难理解,顾名思义:请求超时,什么意思,nginx 没有收到客户端的请求吗?

查看 nginx 日志时,往往会发现 web 容器实际上是很快就响应了,如下

2020-10-02T00:00:01+00:00 408 166679257 1 157.37.132.68 - - 10609 0.337 POST HTTP/1.1 hotapps.com 80 /hotapp/appUpdate - - 80 okhttp/3.8.0 - - 127.0.0.1:8080 200 0.007

web 容器的响应码是 200,耗时为 7 毫秒,而 nginx 的耗时是 337 毫秒,响应码是 408

这么说的话,nginx 根本就是收到了客户端的完整请求,还发给后端的 web 容器,并且都收到了 web 容器的应答

和朋友的讨论

朋友也遇到过类似问题,如下图

nginx 408 (nginx httpstatus 408)已解决

http 408

他的原话是

nginx 的耗时要比反向代理的多的多

有什么想法

我的第一反应是用户提交数据量太大,例如上传视频,这样 nginx 接收上传数据需要大量时间,而后端 jetty 的处理仅仅是数据库操作,这样很符合上图 nginx 耗时 60 多秒而后端耗时 460 多毫秒的现象

但朋友表示还有其他可能

很多请求都是点个赞, 打开视频把播放次数 +1

这客户端应该不会耗时的

我研究了一下 $request_time 这个 nginx 内嵌变量,其说明如下

$request_time

request processing time in seconds with a milliseconds resolution (1.3.9, 1.2.6); time elapsed since the first bytes were read from the client

那么我觉得可以得出以下公式

$request_time = 接收数据时间 + $upstream_response_time + 发送数据时间

现在的情况是 $request_time >> $upstream_response_time,那么问题肯定是出在接收数据或发送数据阶段

分析

发送数据,是发送到本地缓冲区,还是发送到客户端并接收到 ACK?先假定是发送到本地缓冲区吧,那么发送数据时间基本是可以忽略的

  • 当用户操作是上传大文件时,nginx 接收数据肯定是比较耗时的
  • 当用户网速较慢时,用户下载数据肯定也是比较耗时的

那么朋友的这个日志体现出的 nginx 的耗时要比反向代理的多的多 的现象,也就有了解释:用户正处于慢网络(例如 2G 网络)中

HTTP 408

说到这里,再回头看 408 错误码

之前一直认为 408 是在接收数据阶段发生的,但是现在我觉得应该是在整个 request 阶段发生,即还应该包括 $upstream_response_time 和 发送数据 阶段

那就是这个 408 其实是在 nginx 向用户发送数据期间发生的,其原因大概是

  • 要向客户端发送的数据量太大
  • 客户端的网速太慢

基于上述针对这个日志的分析,我有了以下的结论

  • 发送数据:是将数据发送到客户端而不仅仅是发送到本地缓冲区
  • 接收数据超时导致 408 的说法应该是错误的,实际上 nginx 早已接收到数据了

和 499 的区别

408:由 nginx 决定是否为 408,其判断依据是从接收到客户端第一个字节开始直到客户端收到服务器的第一个字节开始所经历的时间

499:由客户端决定是否 499,判断依据是发送数据后等待服务器下发的第一个字节接收到所经历的时间

喜欢 (0)
炮渣日记
关于作者:
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址