国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

微軟的坑:Url重寫竟然會引起IIS內核模式緩存不工作

2019-11-17 03:26:12
字體:
來源:轉載
供稿:網友

萬萬沒有想到!當初為了解決使用負載均衡時記錄客戶端ip地址的問題,在IIS URL Rewrite Module中增加了一條URL重寫規則(詳見遷入阿里云后遇到的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的內核模式緩存(kernel mode caching)被IIS URL Rewrite Module禁用,禁用理由是重寫規則中用到了影響緩存安全的服務器變量(cache unsafe server variable)——{HTTP_X_forwarded_For}。

URL重寫竟然能影響到處于內核模式的http.sys,誰能想到?微軟想到了,而且做到了!

當知道這個真相后,真的很惱火!平時誰會注意http.sys的緩存是否正常工作,如果不是因為最近在解決“黑色1秒”問題,估計再過十年也不會發現。

那我們是怎么發現的呢?借助于Windows性能監視器(Performance Monitor)。

針對http.sys kernel mode cache的性能監視器

在添加了HTTP Service的三個監測項目——TotalUrisCached, UriCachedHits, UriCacheMisses之后發現,TotalUrisCached與UriCachedHits值一直是0,而UriCacheMisses的值巨大無比,一看就知道kernel mode caching出問題了。

后來發現一個命令可以更輕松地進行檢測:

netsh http show cachestate

如果出現上圖的畫面,說明kernel mode caching沒干活。

當我們禁用了讓kernel mode caching罷工的URL重寫規則后,用瀏覽器訪問一個網址,然后Ctrl+F5刷新2次(10秒內被訪問2次就會被http.sys緩存),然后運行命令netsh http show cachestate:

netsh http show cachestate

從上圖中可以看出請求的內容被http.sys成功緩存了。

那內核模式緩存失效會帶來什么影響呢?

誰都知道這會影響了網站的處理性能,而對我們來說還有一個重大影響——在“黑色1秒”問題的排查過程中,它讓我們作出了錯誤的判斷,以為“黑色1秒”期間http.sys進程卡住了(依據緩存沒工作),詳見“黑色30秒”走了,“黑色1秒”來了,真相也許大白了。現在看來,如果解決了http.sys緩存問題,“黑色1秒”期間IIS日志中很可能有緩存輸出的記錄,如果真是這樣,那引發“黑色1秒”的環節可能在WAS(Windows PRocess Activation Service),這將把我們帶向不同的問題排查方向。

那如何解決這個問題呢?

目前只想到兩個方式:

1. 棄用IIS URL Rewrite Module,但目前未找到更好的選擇。

2. 讓阿里云修改SLB的轉發規則,將http headers中的REMOTE_ADDR修改為真實的客戶端IP。

3. 修改代碼,不通過Request.UserHostAddress獲取IP。

【最終選擇的解決方法】

寫了兩個擴展方法:

復制代碼
namespace System.Web{    public static class HttpRequestExtension    {        //針對WebForm        public static string GetUserIp(this HttpRequest request)        {            var ip = request.ServerVariables["HTTP_X_FORWARDED_FOR"];            if(string.IsNullOrEmpty(ip))            {                ip = request.UserHostAddress;            }            return ip;        }        //針對MVC        public static string GetUserIp(this HttpRequestBase request)        {            var ip = request.ServerVariables["HTTP_X_FORWARDED_FOR"];            if (string.IsNullOrEmpty(ip))            {                ip = request.UserHostAddress;            }            return ip;        }    }}
復制代碼

然后將代碼中所有調用Request.UserHostAddress的地方改為調用擴展方法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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 古丈县| 平泉县| 兴和县| 乌什县| 错那县| 新干县| 金塔县| 北辰区| 棋牌| 宜都市| 烟台市| 茶陵县| 乌拉特后旗| 威信县| 邵东县| 墨玉县| 公安县| 黄骅市| 贡山| 二手房| 谢通门县| 连江县| 故城县| 贵阳市| 桑日县| 甘谷县| 瑞金市| 香港| 晋州市| 宜州市| 读书| 临潭县| 定西市| 天柱县| 通许县| 龙陵县| 庄河市| 宁海县| 同仁县| 阿拉善右旗| 兴化市|