windows服務(wù)器Url重寫竟然會(huì)引起IIS內(nèi)核模式緩存不工作
萬(wàn)萬(wàn)沒有想到!當(dāng)初為了解決使用負(fù)載均衡時(shí)記錄客戶端IP地址的問題,在IIS URL Rewrite Module中增加一條URL重寫規(guī)則。竟然造成http.sys的內(nèi)核模式緩存(kernel mode caching)被IIS URL Rewrite Module禁用,禁用理由是重寫規(guī)則中用到了影響緩存安全的服務(wù)器變量。
萬(wàn)萬(wàn)沒有想到!當(dāng)初為了解決使用負(fù)載均衡時(shí)記錄客戶端IP地址的問題,在IIS URL Rewrite Module中增加了一條URL重寫規(guī)則(詳見遷入阿里云后遇到的Request.UserHostAddress記錄IP地址問題):
<rewrite> <allowedServerVariables> <add name="REMOTE_ADDR" /> </allowedServerVariables> <globalRules> <rule name="HTTP_X_Forwarded_For-to-REMOTE_ADDR" enabled="true"> <match url=".*" /> <serverVariables> <set name="REMOTE_ADDR" value="{HTTP_X_Forwarded_For}" /> </serverVariables> <action type="None" /> <conditions> <add input="{HTTP_X_Forwarded_For}" pattern="^$" negate="true" /> </conditions> </rule> </globalRules></rewrite>
這竟然造成http.sys的內(nèi)核模式緩存(kernel mode caching)被IIS URL Rewrite Module禁用,禁用理由是重寫規(guī)則中用到了影響緩存安全的服務(wù)器變量(cache unsafe server variable)——{HTTP_X_forwarded_For}。
URL重寫竟然能影響到處于內(nèi)核模式的http.sys,誰(shuí)能想到?微軟想到了,而且做到了!
當(dāng)知道這個(gè)真相后,真的很惱火!平時(shí)誰(shuí)會(huì)注意http.sys的緩存是否正常工作,如果不是因?yàn)樽罱诮鉀Q“黑色1秒”問題,估計(jì)再過十年也不會(huì)發(fā)現(xiàn)。
那我們是怎么發(fā)現(xiàn)的呢?借助于Windows性能監(jiān)視器(Performance Monitor)。
在添加了HTTP Service的三個(gè)監(jiān)測(cè)項(xiàng)目——TotalUrisCached, UriCachedHits, UriCacheMisses之后發(fā)現(xiàn),TotalUrisCached與UriCachedHits值一直是0,而UriCacheMisses的值巨大無(wú)比,一看就知道kernel mode caching出問題了。
后來(lái)發(fā)現(xiàn)一個(gè)命令可以更輕松地進(jìn)行檢測(cè):
netsh http show cachestate
如果出現(xiàn)上圖的畫面,說明kernel mode caching沒干活。
當(dāng)我們禁用了讓kernel mode caching罷工的URL重寫規(guī)則后,用瀏覽器訪問一個(gè)網(wǎng)址,然后Ctrl+F5刷新2次(10秒內(nèi)被訪問2次就會(huì)被http.sys緩存),然后運(yùn)行命令netsh http show cachestate:
從上圖中可以看出請(qǐng)求的內(nèi)容被http.sys成功緩存了。
那內(nèi)核模式緩存失效會(huì)帶來(lái)什么影響呢?
誰(shuí)都知道這會(huì)影響了網(wǎng)站的處理性能,而對(duì)我們來(lái)說還有一個(gè)重大影響——在“黑色1秒”問題的排查過程中,它讓我們作出了錯(cuò)誤的判斷,以為“黑色1秒”期間http.sys進(jìn)程卡住了(依據(jù)緩存沒工作),詳見“黑色30秒”走了,“黑色1秒”來(lái)了,真相也許大白了。現(xiàn)在看來(lái),如果解決了http.sys緩存問題,“黑色1秒”期間IIS日志中很可能有緩存輸出的記錄,如果真是這樣,那引發(fā)“黑色1秒”的環(huán)節(jié)可能在WAS(Windows Process Activation Service),這將把我們帶向不同的問題排查方向。
那如何解決這個(gè)問題呢?
目前只想到兩個(gè)方式:
1. 棄用IIS URL Rewrite Module,但目前未找到更好的選擇。
2. 讓阿里云修改SLB的轉(zhuǎn)發(fā)規(guī)則,將http headers中的REMOTE_ADDR修改為真實(shí)的客戶端IP。
3. 修改代碼,不通過Request.UserHostAddress獲取IP。
【最終選擇的解決方法】
寫了兩個(gè)擴(kuò)展方法:
<rewrite> <allowedServerVariables> <add name="REMOTE_ADDR" /> </allowedServerVariables> <globalRules> <rule name="HTTP_X_Forwarded_For-to-REMOTE_ADDR" enabled="true"> <match url=".*" /> <serverVariables> <set name="REMOTE_ADDR" value="{HTTP_X_Forwarded_For}" /> </serverVariables> <action type="None" /> <conditions> <add input="{HTTP_X_Forwarded_For}" pattern="^$" negate="true" /> </conditions> </rule> </globalRules> </rewrite>
然后將代碼中所有調(diào)用Request.UserHostAddress的地方改為調(diào)用擴(kuò)展方法Request.GetUserIp()。
【參考資料】
URL Rewrite Module 1.1 for IIS 7
Working with HTTP.SYS or Kernel Mode Caching in Internet Information Services 6.0
URL Rewrite Module Configuration Reference
相關(guān)文章
在IIS 7中配置PHP運(yùn)行環(huán)境簡(jiǎn)單步驟[圖文教程]
在IIS 7中配置PHP運(yùn)行環(huán)境簡(jiǎn)單步驟,需要的朋友可以參考下。2011-06-06IIS7/IIS7.5/IIS8網(wǎng)站目錄執(zhí)行權(quán)限設(shè)置方法(與IIS6不同)
這篇文章主要介紹了IIS7/IIS7.5/IIS8網(wǎng)站目錄執(zhí)行權(quán)限設(shè)置方法(與IIS6不同),需要的朋友可以參考下2016-06-06管理員需要參考的當(dāng)服務(wù)器被入侵后的緊急補(bǔ)救方法
近日有很多站長(zhǎng)服務(wù)器被入侵,被入侵后真是措手不及啊,“站長(zhǎng)安全網(wǎng)”Jack為大家分析服務(wù)器被入侵前后的一些細(xì)節(jié)和處理方式,希望能為大家祈禱拋磚引玉的作用,若有說錯(cuò)指出還請(qǐng)見諒。2009-10-10win2003 服務(wù)器安全設(shè)置教程(權(quán)限與本地策略)
腳本之家的這篇文章主要是補(bǔ)充下以前我們發(fā)的文章,對(duì)于服務(wù)器安全設(shè)置需要掌握很多的東西與技巧2012-07-07windows下配置Apache+PHP+MySQL綠色移動(dòng)版
為了方便管理,先新建一個(gè)目錄,我把他建在 D 盤下,新建文件夾 Web ,然后把 Apache , PHP , MySQL 全放進(jìn)去。2011-01-01