昨天線上進行機房遷移,因爲請求量不大,打算先用nginx進行轉發。結果今天業務反饋,返回的數據,解析出來內容爲亂碼。javascript
上海機房因爲網絡不穩定,須要將機房遷移到無錫。上海機房使用F5進行轉發和負載均衡,遷移到無錫機房因爲資源限制,而且業務訪問量不大,使用nginx進行轉發和負載均衡。css
可是在無錫機房啓動後,發現部分業務收到的部分數據是亂碼。具備必定的隨機性html
因爲業務數據沒法更新,緊急狀況下切換上海機房,無錫機房暫時不啓用。java
從整個訪問流程來看,只有中間的F5換成了Nginx,訪問方PORTAL未變(無配置變更、無升級更新),服務提供方WX_GDC直接從SH_GDC拷貝過來(惟一的變化是數據庫配置)。nginx
Nginx轉發存在一些問題 WX_GDC數據庫亂碼。這個DBA很快確認沒有亂碼,焦點放到Nginx上。數據庫
Nginx在轉發時HTTP協議某些處理有問題瀏覽器
請出網絡神器--tcpdump,抓包對比正常和異常的數據包。緩存
2015-11-21 09:51:04.514918 IP 100.84.73.45.51377 > 100.84.73.34.9920: Flags [P.], seq 418240356:418240642, ack 340809695, win 1024, options [nop,nop,TS val 3214173339 ecr 3214153356], length 286 E..R.W@.@.KLdTI-dTI-..&....d.PW.....\G..... ..d.....POST /Application/pullConfig HTTP/1.1 Host: 100.84.73.34:9920 Accept-Encoding: gzip Connection: keep-alive Accept: */* User-Agent: NING/1.0 Content-Length: 69 Content-Type: application/x-www-form-urlencoded
異常狀況下的請求發送了 Accept-Encodeing: gzip服務器
2015-11-21 09:24:02.983959 IP 100.84.73.50.54462 > 100.84.73.34.9920: Flags [P.], seq 1:301, ack 1, win 115, options [nop,nop,TS val 3212551808 ecr 3054521289], length 300 E..`.+@.@.0udTI-dTI"..&..M.WPR.....s\J..... .{....POST /Application/pullConfig HTTP/1.1 Host: 100.84.73.34:9920 Connection: Keep-Alive
正常狀況下的請求沒有發送 Accept-Encodeing: gzip網絡
瞬間意識到是因爲nginx將請求結果進行了gzip壓縮,可是爲什麼有的業務能夠正常處理,而又得業務獲得結果爲亂碼。
無異常A業務答覆:咱們使用Java的原生URL類進行請求。
有異常的B業務答覆:咱們使用AsyncHttpClient進行請求。
查找AsyncHttpClient的使用,發現默認的方式是Accept-Encoding爲gzip,可是須要在獲取內容後,進行gzip解壓。而B業務未進行相關的處理
這裏有一篇文章講的很好。http://www.cnblogs.com/TankXiao/archive/2012/11/13/2749055.html
B業務反饋其在部分狀況下也是沒有亂碼的,看着具備隨機性。爲什麼會這樣?
翻閱nginx gzip的配置發現:gzip_min_length 配置,若是配置,則小於這個值不進行壓縮,大於這個值進行壓縮。
Nginx關於gzip的配置學習
gzip on; //該指令用於開啓或關閉gzip模塊(on/off)
gzip_min_length 1k; //設置容許壓縮的頁面最小字節數,頁面字節數從header頭得content-length中進行獲取。默認值是0,無論頁面多大都壓縮。建議設置成大於1k的字節數,小於1k可能會越壓越大。
gzip_buffers 4 16k; //設置系統獲取幾個單位的緩存用於存儲gzip的壓縮結果數據流。4 16k表明以16k爲單位,安裝原始數據大小以16k爲單位的4倍申請內存。
gzip_http_version 1.1; //識別http的協議版本(1.0/1.1)
gzip_comp_level 2; //gzip壓縮比,1壓縮比最小處理速度最快,9壓縮比最大但處理速度最慢(傳輸快但比較消耗cpu)
gzip_types text/plain application/x-javascript text/css application/xml //匹配mime類型進行壓縮,不管是否指定,」text/html」類型老是會被壓縮的。
gzip_vary on; //和http頭有關係,加個vary頭,給代理服務器用的,有的瀏覽器支持壓縮,有的不支持,因此避免浪費不支持的也壓縮,因此根據客戶端的HTTP頭來判斷,是否須要壓縮