windows服务器Url重写竟然会引起IIS内核模式缓存不工作
万万没有想到!当初为了解决使用负载均衡时记录客户端IP地址的问题,在IIS URL Rewrite Module中增加一条URL重写规则。竟然造成http.sys的内核模式缓存(kernel mode caching)被IIS URL Rewrite Module禁用,禁用理由是重写规则中用到了影响缓存安全的服务器变量。
万万没有想到!当初为了解决使用负载均衡时记录客户端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 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:

从上图中可以看出请求的内容被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。
【最终选择的解决方法】
写了两个扩展方法:
<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>然后将代码中所有调用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
相关文章
Windows Server 2012 R2或2016无法安装.NET Framework 3.5.1的解决方法
这篇文章主要为大家详细介绍了Windows Server 2012 R2或2016无法安装.NET Framework 3.5.1,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2017-05-05
IIS6、IIS7.5设置网站默认首页方法(Directory Listing Denied)
这篇文章主要介绍了IIS6、IIS7.5设置网站默认首页方法,如果不设置访问目录就会提示Directory Listing Denied,就是不允许列出文档,为了安全网站都会设置不设置默认,需要的朋友可以参考下2017-03-03
Windows安装MySQL8.0.16 的步骤及出现错误问题解决方法
现在的mysql8安装只能采用解压配置版,像以前老版本的傻瓜式安装将不复存在。下面小编给大家带来了解决Windows安装MySQL8.0.16 步骤及出现错误问题,感兴趣的朋友一起看看吧2019-06-06
WebsitePanel Standalone Server安装配置方法
这篇文章主要为大家介绍下WebsitePanel安装后的配置方法,结合了上一篇文章,需要的朋友可以参考下2013-12-12
安装IIS时如果老提示无法复制convlog.exe、iisadmin.mfl等文件
IIS出了点问题,就重新安装。于是在安装IIS时如果老提示无法复制convlog.exe、iisadmin.mfl等文件。2011-01-01
Windows Server 2019 Web服务器搭建的实现步骤
Web服务器可以接收其他计算机中的浏览器发来的请求,本文主要介绍了Windows Server 2019 Web服务器搭建的实现步骤,具有一定的参考价值,感兴趣的可以了解一下2024-04-04
windows server 2019 服务器配置的方法步骤(大图版)
Windows Server 2019具有管理本地和Azure资源的混合功能,以及众多使其优于Windows Server 2016的其他高级功能,推荐大家安装win20192022-08-08


最新评论