从 nginx 访问日志中的400错误说起

红薯 发布于 2011/12/20 08:18
阅读 9K+
收藏 14

在研究 OSCHINA 也在遭受大量的无效请求 这个问题时找到的一篇文章,转载于此:

最近在整nginx+php+mysql的网站架设,发现nginx的access.log文件(也就是访问日志)中有大量的400错误,知道HTTP状态码的童鞋都知道这个状态码表示错误的客户端请求,换句话说是服务器无法理解客户端的请求。

服务器中的错误记录类似于这种:
127.0.0.1 - - [01/Oct/2011:11:51:04 +0800] "-" 400 0 "-" "-" "-"

踩点:

经过分析nginx的log文件,发现都是在一次正常访问之后产生的数个400错误,每次有大概连续出现1-6个不等,而且也并不是每次客户访问都会产生400错误。

再观察产生400错误的前一次访问是很正常的,200状态码,正常的文件,正常的来路,正常的User-Agent... 一切都很和谐,那400是肿么来的呢?

通过仔细观察发现,所有产生400错误的前一次访问的User-Agent都是Google Chrome浏览器留下的,也就是说400错误是由Chrome浏览器产生的。但是经过本地抓包发现,chrome是没有向服务器发送异常请求或者数据包的。

在抓包分析中发现,Chrome在访问服务器时发起的连接不止一个,一般有5到6个不等,而如果请求的资源不需要那么多连接时,Chrome就会关闭未用的连接,这项技术叫做pre-connection“预先连接”。

通常我们访问一个网站时,第一个获取的是一个html主文件,而里面链接了网页所需要的css、js、图片等其他媒体资源文件,而一般资源文件和主 html文件是在一个域下的,预先连接就是在获取html之前就建立很多的tcp连接,而不是等到获取到html文件之后再去连接服务器获取其他的文件, 因为连接服务器是需要消耗一些时间的,所以这项技术可以很大程度上加快网页的呈现速度。

如果网页html链接的资源比较少,或者客户端有缓存,不需要连接下载,那么Chrome浏览器发出的5-6个连接很可能只有1个是需要的,其他的 都得关闭掉,这样就产生了一个问题:连接了服务器,而没有发送任何请求。对于这种情况,nginx是当做400错误来处理的,但由于连接已经关闭,错误信 息不会发送到客户端,这就产生了日志文件中记录了错误,而抓包分析中什么也看不到的现象。

测试:

要验证上面的分析结果很简单,打开命令行cmd.exe,在里面输入telnet serverip 80,等待连接成功之后直接关掉cmd,这时去查看nginx的log文件中就多了一条400错误记录。

一句评论:

pre-connection的优点已经很清楚了,但是它也是有缺点的,如果站长做了优化,使用了Cookie-free技术,或者网页和静态资源 使用不同的服务器,那么网页需要的css、js资源就和主html不在同一个域下,也可能不在同一个IP上,那么pre-connection不仅是鸡 肋,而且会对主html服务器产生不必要的负担。

文章出处:http://www.shily.net/topic/speaking-from-400-error-in-nginx-access-logs/

 

加载中
0
mark35
mark35

原来如此。

还有精华标签呀~

0
夏文雄
夏文雄
我觉得不对,我现在还在完善系统,在看日志的时候根本没有人访问,但是依旧打这个日志。
0
无夏之年
无夏之年
怪不得。最近看Nginx日志,也是发现了好多奇怪问题,众人皆莫能解。
0
蟋蟀哥哥
蟋蟀哥哥
最后是怎么解决的?
sjack
sjack
我也想问,,,
0
小杨阿哥哥
小杨阿哥哥
浏览器也是想尽办法加快速度啊·
0
lengspring
lengspring

这个问题怎么解决?站长?困扰我很久了,我在IE6下访问有400输出,其他浏览器都正常,而且出现400的时候访问会卡顿几秒,然后再200:

日志:

10.79.4.181 - - [11/Mar/2013:10:46:44 +0800] "-" 400 0 "-" "-" "-"
10.79.4.181 - - [11/Mar/2013:10:46:44 +0800] "-" 400 0 "-" "-" "-"
10.79.4.181 - - [11/Mar/2013:10:46:44 +0800] "-" 400 0 "-" "-" "-"
10.79.4.181 - - [11/Mar/2013:10:46:44 +0800] "-" 400 0 "-" "-" "-"
10.79.4.181 - - [11/Mar/2013:10:46:44 +0800] "GET /index.php?app=product&action=product_list HTTP/1.1" 200 3873 "http://10.0.16.99/index.php?app=vendor&action=vendor_list" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; CIBA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET4.0C)" "-"

0
lengspring
lengspring

网上都说http header存入cookie值过大

client_header_buffer_size 32k;
large_client_header_buffers 4 128k;

改这两项完全是吹牛逼的,实验了好多次了,压根儿不是这个问题,求帮助站长,谢谢!

0
lengspring
lengspring

问题解决了,爽了,哈哈

http://www.oschina.net/question/110450_92678

0
syw1990
syw1990
400不一定是存在错误,可能是浏览器预加载造成,这篇文章测试了。
http://www.ihref.com/read-16479.html
返回顶部
顶部