文章出處

冒著被大家厭煩的風險,今天再發一篇“云計算之路-阿里云上”。這是在前一篇發過之后真實發生的事情,我們覺得定位問題的過程值得分享。而且估計園子里不少朋友被這個問題騷擾過,我們有責任讓大家知道問題的真正原因。

快下班之前,園區里另外一家公司的朋友說他們公司有的人不能正常訪問園子——會出現HTTP Error 400錯誤,而其他人可以正常訪問。這個問題立即引起了我們的警覺,因為之前也有園友反饋過同樣的問題,當時什么也沒動,后來就好了,以為是他們公司網絡代理服務器的問題。由于我們從未遇到過這個問題,而且無法重現,也就無從下手。現在再次出現這個問題,也是有代理服務器的網絡環境,難得的機會,我們立即去現場一看究竟。

在遇到這個問題的電腦上,不管用什么瀏覽器,訪問www.cnblogs.com都會出現錯誤:

Bad Request - Invalid Hostname
HTTP Error 400. The request hostname is invalid.

這是IIS返回的標準400錯誤,說明請求已經由SLB(阿里云負載均衡)到達了Web服務器。

我們查看了瀏覽器的請求頭,一切正常。

在查看Cookie時發現只有一個名為SERVERID的Cookie,于是我們清除一下這個Cookie,結果html頁面出來了,但后續的css/js文件加載時又出現400錯誤,再刷新瀏覽器,又變成400錯誤。

這個SERVERID的Cookie讓我們想起了在排查“黑色30秒”問題期間,我們開啟了SLB的會話保持,這個Cookie是SLB為了保持會話而產生的。難道與SLB會話保持有關?“Bad Request - Invalid Hostname”時,IIS收到的究竟是什么樣的hostname?

帶著這些問題,我們回到了自己的辦公室,立即想到了IIS的一個重要日志——httperr日志,默認存放位置是C:\Windows\System32\LogFiles\HTTPERR\文件夾,打開一個日志文件一看,滿眼都是400錯誤,錯誤的原因都是Hostname。

之前我們在偶爾看httperr日志時,也看到過這樣的400錯誤,當時想可能是某些出問題的爬蟲引起的,SLB怎么可能會把hostname搞錯,也就沒深究。

這次一定要找出IIS究竟收到的是什么樣的hostname,那如何讓IIS在httperr中記錄hostname的信息呢?

在網上找到了一篇微軟的參考資料:Additional properties are now available for logging in the Httperr#.log file in IIS 6.0 and IIS 7.0

只需2步操作實現:

1. 在注冊表項HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\HTTP\Parameters中添加名為ErrorLoggingFields、類型為REG_DWORD、值為7DFF4E7 (十六進制)的項目。

2. 在命令行中運行命令:net stop http & net start http & iisreset

然后再查看httperr日志,結果讓我們驚呆了,cs-host中竟然有這樣的值(見下圖):

第1張圖中SLB竟然把http header中的max-age=259200當作host的值轉發給了IIS。

第2張圖片SLB竟然把用戶在使用代理服務器的情況下得到的IP信息當作host的值轉發給了IIS。

難怪會出現Invalid Hostname的錯誤!

對于SLB這樣的角色,http header失之毫厘,謬以千里。出現這樣的問題,真的讓人覺得這地方的代碼寫得很糟糕。

如果SLB的代碼是開源的?哪個開發人員敢寫出這樣的代碼?即使敢寫,也馬上會被人發現。

看來云計算更需要開源,不是把開源變成自己的計算能力,而是把自己的計算能力開源,這樣才能更少問題、更讓人放心。

禁用SLB的會話保持后,這些400立馬消失。

一想到因為這個原因造成很多用戶不能正常訪問,就有一種說不出的惱火。。。

【更新】

阿里云已于2014年5月22日修復這個問題。


文章列表


不含病毒。www.avast.com
全站熱搜
創作者介紹
創作者 大師兄 的頭像
大師兄

IT工程師數位筆記本

大師兄 發表在 痞客邦 留言(0) 人氣()