万神劫

万物天地为剑,神鬼妖邪为剑
劫波万渡,宇宙苍穹尽为剑
是为万神劫!

8条评论 2012-07-02

Nginx 日志中神秘的 HTTP 400 错误

前几天在查看 Nginx 的访问日志时,发现大量 HTTP 返回码为 400 的记录,见下图

可以看到,除了记录了 IP 以及返回码之外,日志中请求的 URL, Referer, User Agent 等等的信息通通为空白,非常奇怪

根据 HTTP 协议,400 返回码表示服务器认为浏览器发送的请求有错误,参见 HTTP 400 型错误 -请求无效
但是正常通过浏览器访问时,怎么会出现请求错误呢?

我立刻打开自己的 Chrome 浏览器试着访问了一下博客首页,发现居然又出现了三次 400 的记录,IP 自然都是我自己
反复试验,此现象基本都能重现,而且有一个很重要的特征:400 记录并不是紧随着正常记录,而是与之有大约几秒钟的间隔

看来是 Chrome 在请求完网站之后,间隔一段时间后,又发送了几条请求到服务器,但是请求的内容有问题,无法被服务器识别
Chrome 发送的是什么样的请求呢?我立刻打开 SmartSniff 抓取了一下 TCP 的包,见下图

注意选中的那三条记录的字节数,1 Byte ,原来 Chrome 发送了一条空的请求给服务器,所以服务器自然返回 400 了
至此,再结合上面所发现的特征,基本可以猜出原因了:与 Chrome 的并发连接数有关系!

我的判断是:

  • 浏览器对于同域名的请求有并发连接数的限制,而 Chrome 的这个并发数的数值很高
  • Chrome 访问一个网页时,会立刻建立大量的 TCP 连接,以便进行后续的 HTTP 传输
  • 如果此网页的外部资源较少,导致部分 TCP 连接不需要使用,那么在一段时间后,Chrome 会断开这个连接
  • 断开连接时,Chrome 的处理方式是发送一个空请求给服务器,造成服务器报 400 错误

为了验证这个判断,我给首页加了一个 img 标签,增加了首页的一个前端资源,然后再访问网站
果然,几十秒之后,日志中只出现了 2 条 400 记录,比之前的少了一条,基本验证了以上我的判断
另外试验了一下IE8 ,发现并不会造成 400 错误,而根据资料,这两个浏览器的并发数都是6,看来这可能属于 Chrome 处理策略上的问题了
呵呵,看来有时候网页外链的资源少了,也会出现烦恼啊...

PS: 谁知道怎么修改 Chrome 的并发连接数?找了 N 久,貌似不支持嘛...

comments powered by Disqus