為什麼IIS7/7.5的Gzip不起作用
我在IIS7配置Gzip壓縮一文中介紹了IIS7對於gzip壓縮的相關配置,以及預設情況下,由於IIS7將Javascript配置為動態壓縮(Dynamic Compression),受CPU還有其他因素的影響,不一定會返回gzip壓縮後的內容。 但是前陣子發現,儘管將Javascript配置成了靜態壓縮,請求Javascript指令碼檔案的時候偶爾還是會出現沒有gzip的情況。這篇文章和大家分享一下我遇到的這個問題以及解決這個問題的過程和思路,希望對大家有所幫助。
“隨機”的gzip行為
問題的症狀非常簡單而又奇怪。有時候連續訪問指令碼多次,剛開始沒有gzip,再次訪問又有gzip。等過好一會再去訪問,gzip又沒有了。有的時候則是無論怎麼訪問都不給我返回gzip後的響應。
問題的分析
排除了CPU負載過大的因素,因為發現當深夜機器CPU負載正常的時候也一樣出現這樣的問題。
在系統日誌中發現以下Warning條目,引起了我的注意:
Warning 2010/4/13 6:32:41 IIS-W3SVC-WP 2264 None
The directory specified for caching compressed content C:\inetpub\temp\IIS Temporary Compressed Files\XXX is invalid. Static compression is being disabled.
通過日誌篩選,發現從09年7月份就一直出現這樣的Warning了,而且出現頻率是隔1-3天左右。
這個資料夾是IIS用於存放壓縮後的靜態內容快取。按照上面日誌的意思,是說這個目錄出了問題,導致靜態壓縮功能被禁用了。但是我明明可以訪問這個資料夾,而且裡頭確實還放著快取的指令碼。
IIS論壇上提這個問題的帖子很多,但最終得到解答的沒看到。不過其中一些人的回覆倒是給了我不少思路。其中有人說道可能是資料夾許可權問題,我看了看那個壓縮快取目錄,上面的許可權的確是應用程式池的身份,沒有問題。使用ProcessMonitor監測了w3wp.exe程序的活動情況,沒有看到這個程序在訪問檔案系統時出現錯誤。
後來在網上看到了Kanwaljeet Singla(IIS開發團隊成員)的一篇文章,介紹IIS7相比IIS6在壓縮模組上的改動,文中提到了一點,從IIS7開始,為了降低開銷,IIS只對那些頻繁訪問的靜態資源啟用壓縮。通過IIS7新引入的兩個配置選項frequentHitThreshold和frequentHitTimePeriod,我們可以設定,當某個資源在frequentHitTimePeriod時間內被連續訪問了frequentHitThreshold次,那麼就算是“頻繁訪問”了。預設的配置是10秒鐘內連續對同一Url發起2次請求就算此Url對應的資源屬於頻繁訪問的資源,IIS伺服器就會對其進行壓縮,然後丟入快取目錄。
這也就解釋了為什麼有時候第一次請求指令碼的時候,伺服器沒有返回gzip壓縮後的內容,而是等你接著下一次訪問的時候才會返回gzip響應。
但是按照這篇文章提到的IIS的設計理念,一旦資源被壓縮快取過,那麼以後就不會再應用這個“頻繁訪問”的檢測邏輯了,因為畢竟已經沒有壓縮開銷了。而我非常確信這個指令碼已經被快取在伺服器硬碟上了,那為什麼我過一段時間再去訪問的時候還是沒有gzip呢?
在IIS7中有一個功能,叫做失敗請求跟蹤(Failed request tracing),允許技術人員跟蹤那些出問題的請求在IIS內部都發生了什麼事。為了揭開我的疑問,我對此網站開啟了失敗請求跟蹤。
IIS7的Bug?!
開啟IIS7管理器,定位到相應的網站右側的操作面板,開啟“失敗請求跟蹤”。預設跟蹤日誌檔案是存放在%SystemDrive%\inetpub\logs\FailedReqLogFiles目錄中。
然後在功能面板中找到“失敗請求跟蹤規則”進行配置:
為了防止其他指令碼的干擾,在這裡我限定了只跟蹤測試的指令碼
響應狀態填寫200即可
接下來是選擇跟蹤提供程式,也就是給你提供跟蹤日誌源的程式,由於我們的指令碼只經過靜態檔案處理器,因此這裡我們只需要選擇www server處理程式即可。
然後我們就可以去測試一下訪問出問題的指令碼了。一旦IIS中途處理遇到些問題,那麼就會以xml形式記錄下相關的日誌。開啟FailedReqLogFiles目錄,裡頭會有一些fr000001.xml這樣格式的檔案,每個檔案代表一次失敗請求。我們開啟這個檔案,查詢compression關鍵詞,發現了以下內容:
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
< System >
< Provider Name = "WWW
Server" Guid = "{3A2A4E84-4C21-4981-AE10-3FDA0D9B0F83}" />
< EventID >0</ EventID >
< Version >1</ Version >
< Level >4</ Level >
< Opcode >3</ Opcode >
< Keywords >0x40</ Keywords >
< TimeCreated SystemTime = "2010-05-13T16:59:08.086Z" />
< Correlation ActivityID = "{00000000-0000-0000-FD2B-008041000061}" />
< Execution
|