记录一次"失败"的Windows Server优化案例
分类: Windows Server ◆ 标签: #Azure #Virtual Host #Windows #.Net ◆ 发布于: 2023-06-15 19:52:01
近期将自己的博客移动基于Windows Server 2019 Datacenter
的Azure
虚拟机上,这个虚拟机使用了标准的Azure B2s
的机型,从参数上看是2个vCore
, 4G的内存,IOPS是1280,之前采用的是基于Ubuntu Server 20.04 LTS
版本的机器,虚拟机的大小是一样的。但是我发现将博客迁移到Windows Server
上之后,发现性能提升巨大,这确实颠覆了我的认知,一直以来我都认为是Linux
的性能是要好于Windows
的。
因此我自己做了一个技术上的总结,对比了一下,在相同硬件的情况下,为什么Windows
会速度有这么大的提升。抛开操作系统的设计不谈,毕竟这不是我的强项,从架构上,以及Web应用我是可以归纳一些原因的:
在Linux上我采用的架构是开源社区及其推崇的架构:nginx + .Net Core的
Kestrel
, 依据官方的推荐配置了相应的配置,主要有:- 使用
Systemd
来管理.Net
应用 nginx
的反向代理不监听loopback
转为监控unix socket
, 同时启用了/dev/shm 来放置unix socket
, 减少反向代理时请求loopback
设备的损耗。- 优化了
nginx
的参数。
- 使用
在
Windows Server 2019 Datacenter
上我主要是使用了IIS 10.0
+Asp.net Core Module
, 从而使用Asp.net Core
的IIS
实现,不使用Kestrel
, 同时在部署网站的时候选择了in-process
的模式,也即.Net
的代码和IIS
的w3wp
在同一个进程里,免去了额外的通讯, 其他没有做什么额外的优化。同时做了一些Window Server
上的目录分布以及权限的配置。首先最重要的一个原因,我认为是因为
IIS
和Asp.net Core Module
的集成方式,IIS
和.Net
的代码直接在同一进程中通讯,我认为这会比在Linux上通过nginx
反向代理要快上很多个数量级。通过查看
Windows Server
的优化文档,文档中提及针对HTTP.sys
默认的优化,也即Windows
的内核缓存上。IIS
本身提供的用户缓存。
由于我的博客仅仅是一个很小的几乎是静态的页面,同时我启用了IIS
的动态压缩,因此最开始我认为是由于:in-process
模式部署,HTTP.sys的内核缓存,以及IIS
的用户缓存,以及IIS
的动态压缩,这些原因导致了Windows
的性能更好,当然也少不了HTTP.sys
的连接管理功能。
本来还挺心安理得,觉得是一个很明智的选择,结果有一天晚上,突发奇想,我既然适用了这么多的缓存,那么我怎么这些缓存的命中率咋样呢?起了多大的作用呢?
赶紧找了一下技术文档,发现有几个方法可以进行查看。
方法一:直接使用netsh http show cachestate
查看内核缓存的状态,然后我兴致勃勃的,开始写了一个小脚本,使劲的刷一个页面,结果发现:
啊?!! 尴尬了,咋回事?难道是我用错了命令?一点都没有输出啊。。。。赶紧去查了windows的官方文档,仔细看了一下这个命令,以及帮助。没错就是这么用的。这。。。。咋回事?我的缓存呢?
不信邪的我,继续用第二招:
启动性能监视器, 然后查看指标:
嗯?几个指标UriCacheHits
, TotalUriCached
, CurrentUrisCache
都是0啊!!!!
奔溃了,咋办?
别急,还有一招。放大招。使用IIS
的Freb Trace
。
按照如下的步骤临时启用Freb Trace
:
启动
IIS
管理器,选择自己的站点,然后右侧选择Failed Request Tracking Rule
, 双击进入,然后选择右边菜单上的Edit Site Tracking
:
如下图:
然后启用trace:
然后再添加规则,添加上图中的`Add...', 出现对话框之后:
然后一路'Next`, 配置好了之后,继续刷页面。然后到保存
freb
的目录里查看,看到日志文件如下图:
从图上可以看到一般的路径以及文件名。
用浏览器打开一个,按如下图确认是你访问的文件地址:
看图标处,第一个是文件地址,第二个是我们要关注的地方。点击
Request Detail
之后,搜索cache
:
然后就看到这个:
嗯,咋回事?说是没有启用?
使用
netsh http
确认一下:
说明是启用了的。
就觉得很郁闷,感觉很奇怪,后来在大佬的指点下,屏蔽了Asp.net Core module
的Handler
仅仅使用静态文件发现居然可以了~~~~~
由此怀疑是不是Asp.net Core Module
完全不使用HTTP.sys
以及IIS
的缓存啊。。。
最后终于发现文档:
https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/iis/modules?view=aspnetcore-6.0
HttpCache
模块压根就不会被Asp.net Core
使用,如下图:
也就是说基于IIS
+ Asp.net Core module
的in-process
模式是完全没有使用内核缓存和IIS的用户缓存的,完全是由Asp.net Core
的Response Cache middler
来接管的。
这样就更有意思了。同样是在同一套代码和同一套runtime
下,in-process
的模式可以有如此大的提升?
虽然这次优化不是我想的那样,但是我对于Windows
更感兴趣了,是时候好好的研究一下了。