微服務中的Bad Request
場景描述
我們的系統是基於rest的微服務架構,各個子系統的呼叫都是通過HTTP請求來互動的,並且請求引數要經過base64編碼。
前端時間在做一個數據遷移需求的時候時候,發現總是有一些資料莫名其妙的丟失,當初是根據資料的自增id分段做的遷移,一次遷移一部分。遷移過程會去另一個系統呼叫一個服務確認這些資料是否都屬於要遷移範圍。
遷移過程中發現數據丟失之後,我們查詢日誌發現有Bad Request錯誤。經過定位發現是呼叫資料有效性確認的服務發生了問題。當初我們的段長度是1000,發生這個問題後我們翻看這個服務的細節發現他處理請求的型別是GET,也就是說它的請求資料和地址長度受WEB伺服器的URL長度限制。我們的URL長度過長導致了這個問題。因為這個GET問題迎來了我們的質檢。
從中我們也可以體會到,當我們在對問題進行抽象的時候,不可避免的會隱藏掉底層的一些細節,就如我們通過TSP服務名去標識服務的時候,我們就丟失了對這個請求型別的直接感知。所以工作中還是要多想一想,多看一看,三思而後動,不然回頭就會浪費更多的時間。
現在收集了一些關於URL長度的資訊:
在http協議中,其實並沒有對url長度作出限制,往往url的最大長度和使用者瀏覽器和Web伺服器有關,不一樣的瀏覽器,能接受的最大長度往往是不一樣的,當然,不一樣的Web伺服器能夠處理的最大長度的URL的能力也是不一樣的。
下面就是對各種瀏覽器和伺服器的最大處理能力做一些說明.
Microsoft Internet Explorer (Browser)
IE瀏覽器對URL的最大限制為2083個字元,如果超過這個數字,提交按鈕沒有任何反應。在我的測試中,這個數字得到驗證。
Firefox (Browser)
對於Firefox瀏覽器URL的長度限制為65,536個字元,但當我測試時,最大隻能處理8182個字元,這是因為url的長度除了瀏覽器限制外,還會受Web伺服器的限制,而我本機使用的是ubuntu apache伺服器,最大處理能力為8192個字元(相差10個字元,不知道是什麼原因),一旦超過這個長度,伺服器就返回如下錯誤資訊。
Safari (Browser)
URL最大長度限制為 80,000個字元。
Opera (Browser)
URL最大長度限制為190,000個字元。
Google (chrome)
url長度一旦超過8182個字元時,出現如下伺服器錯誤:
寫道
Request-URI Too Large
The requested URL's length exceeds the capacity limit for this server.
Apache/2.2.12 (Ubuntu) Server at 127.0.1.1 Port 80
Apache (Server)
能接受最大url長度為8,192個字元,但我的測試資料是8,182,10個字元,差別不在,資料具體符合。
Microsoft Internet Information Server(IIS)
能接受最大url的長度為16,384個字元。
通過上面的資料可知,為了讓所有的使用者都能正常瀏覽,我們的URL最好不要超過IE的最大長度限制(2038個字元),當然,如果URL不直接提供給使用者,而是提供給程式呼叫,側這時的長度就只受Web伺服器影響了。
注:可能有些朋友會想當然的認為,如果最大長度限制為2038字元,是不是引數差不多可以傳遞1000個左右的漢字。這樣認為其實是不對的,對於中文的傳遞,最終會為urlencode後的編碼形式進行傳遞,如果瀏覽器的編碼為UTF8的話,一個漢字最終編碼後的字元長度為9個字元。
更詳細資訊可以參考: http://www.cnblogs.com/henryhappier/archive/2010/10/09/1846554.html