如何优化运行在Windows Server和IIS上的Web应用
分类: Windows Server ◆ 标签: #Azure #基础 #Virtual Host #.Net #Windows #Web ◆ 发布于: 2023-06-15 19:55:35

近期将原来运行在Azure Linux
虚拟机上的博客迁到了基于Azure Windows Server
的环境上,发现运行速度大大提升。感慨下,原来之前开源社区忽悠了我这么多年,什么Linux
的性能比Windows
好哦。之前说啥什么Linux
比Windows
安全这个我是一直不信的,因为我是遭受过Linux
被入侵的毒打事件的,说Linux
安全的人估计从来没有遭受过Linux
系统被入侵的毒打,这之后我去恶补了很多安全相关的知识,才发现对于Linux
不了解,不熟悉的人使用Linux
几乎和裸奔没有区别,但是Windows
就不一样,作为商业系统,特别是服务器版,开箱即用,只要遵守微软的最佳实践,保持更新,基本不太会遇到大的安全事故。所以说Linux
比Windows
安全我就从来没有信过。但是我是一直相信Linux
性能会比windows
好,直到这次自己做了迁移才发现,开源社区的话信一半就很多了。
记录一下自己升级和优化的过程。
选择合适的硬件。
这一点是写在微软优化指导文档上,如何选择合适的硬件。不过对于我这个网站来说,没得选择,我直接使用的是Azure
的B2s
类型的虚拟机,这个类型的虚拟机是两个vCPU
和4G
内存,以及最大的IOPS
是1280。 费用在一个月35刀左右,人民币在240左右吧。选择合适的操作系统版本
这个在选择基于Windows
的服务器版本时非常重要,不像Linux
的发行版,收费类型的Linux
发行版会好一些,像Red Hat Enterprise
,OpenSuse enterprise
等, 选择其他的免费的Linux
发行版时,问题是真多。真心不建议将免费Linux
发行版用在产线上,自己玩玩就好。选择Windows
服务器的发行版一定要仔细阅读微软提供的说明,搞清楚选择的发行版本支持哪些功能,有哪些特性,有什么要求等等。我选择的是windows Server 2019 Datacenter
版本。这个版本功能是最为强大的。操作系统的最佳做法
操作系统需要注意的是干净安装,一定不要选择网上的那些版本,特别是国内什么工作室做的版本之类,最好用微软官方下载的镜像,干净安装。不要安装无关的应用和服务。直接选择Web
服务器角色安装。减少磁盘访问的干扰,尽可能的将页面文件(虚拟内存的页面文件), 操作系统,
Web
数据,IIS
日志置于不同的磁盘。当然选择Azure
虚拟机可以根据不同需要挂载不同的磁盘,不过我的网站小,没必要。NTFS
文件系统有一个设置:NtfsDisableLastAccessUpdate (REG_DWORD) 1
位于 HKLM\System\CurrentControlSet\Control\FileSystem 下,默认设置为 1。 此开关针对上一个文件或目录访问禁用日期和时间戳更新,因此可以降低磁盘 I/O 负载和延迟。 干净安装 Windows Server 2022、Windows Server 2019、Windows Server 2016、Windows Server 2012 R2、Windows Server 2012、Windows Server 2008 R2 和 Windows Server 2008 即可默认启用此设置,不需调整。 如果不确定用注册表编辑器找一下这个设置,编辑一下,设置为1。理解
Windwos Server Web
服务器基本架构我研究了一下
Windows Server Web
服务器的基本架构,我认为这个架构比起Linux的可能要好很多,Windows Server
直接将Web
处理的一部分当成操作系统内核的驱动直接放入了内核空间,也就是我们常常见到的Http.sys
内核模块。Windows
使用这个内核模块来接受和路由来自Http
的请求,并且在这一层使用了缓存。大致总结一下Http.sys
干了那些事:- 连接管理和请求处理。
- 缓存
- 路由请求到工作进程
可以用一下官方的图,展示一下这个模型是什么样的:
优化基于
Windows Server
的Web
平台前面我们浏览了一下
Windows Server
的Web
平台基本架构,那么我们如果要优化基于Windows Server
的Web
平台需要从如下几个方面入手:- HTTP.sys以及关联的内核模式缓存。
- 工作进程以及用户模式IIS,包括应用程序池的配置。
- 影响性能的某些参数调整。
HTTP.sys
性能相关主要包括两个方面:缓存和连接管理,这个部分全部在注册表如下的路径中管理:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Http\Parameters
, 需要注意的是更改了这里的参数,需要重启windows
。下面是 HTTP.sys 内核模式缓存的一些有用设置:
- UriEnableCache 默认值:1
如果值为非零值,则启用内核模式响应和片段缓存。 对于大多数场景,缓存应保持启用状态。 如果需要很低的响应和碎片缓存,请考虑禁用缓存。 - UriMaxCacheMegabyteCount 默认值:0
一个非零值,该值指定可用于内核模式缓存的最大内存。 默认值为0,使系统能够自动调整可用于缓存的内存量。
注意 指定大小仅设置最大值,系统可能不允许缓存大小增长到指定值。 - UriMaxUriBytes 默认值:262144字节 (256 KB)
内核模式缓存中条目的最大大小。 不会缓存大于这个大小的响应内容。 如果有足够的内存,请考虑增加限制。 如果内存有限,返回给用户的内容size又比较大,那么可以考虑降低这个值。 - UriScavengerPeriod 默认值:120秒
清理程序会定期扫描 HTTP.sys 缓存,并删除清除程序扫描之间未访问的条目。 将清除周期设置为较高的值将减少清除清理的次数。 但是,缓存内存使用量可能会增加,因为在缓存中可以保留较旧、不经常访问的条目。 将该时间段设置得过低会导致清除清理次数过多,并可能导致刷新和缓存改动过多。
需要注意的是
Windows Server 2022
中HTTP.sys
会自动管理连接和请求,因此之前很多的配置都不起作用了,但是如果您使用的不是Windows Server 2022
,而是之前的版本,那么可以考虑使用如下的文章来详细的调整Http.sys
的参数:https://docs.microsoft.com/en-us/troubleshoot/developer/webapps/iis/iisadmin-service-inetinfo/httpsys-registry-windowsIIS
用户模式的配置IIS
的用户配置基本都在配置文件%SYSTEMROOT%\System32\inetsrv\config\applicationHost.config
里面。
另外如果您的硬件支持NUMA
, 也可以更改注册表项:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\InetInfo\Parameters\ThreadPoolUseIdealCpu
, 模型情况下这个配置自windows Server 2016
之后会自动开启的。用户模式的缓存设置:
用户模式缓存是作为一个模块来实现的,该模块侦听集成管道引发的全局缓存事件。 若要完全禁用用户模式缓存,请从 applicationHost.config 的 System.webserver/globalModules 配置节中的已安装模块列表中删除 FileCacheModule (cachfile.dll) 模块。
system.webserver/cache属性 说明 默认 Enabled 当设置为 False时,禁用用户模式的 IIS 缓存。 如果缓存命中率非常小,则可以完全禁用缓存,以避免与缓存代码路径相关联的开销。 禁用用户模式缓存不会禁用内核模式缓存。 True enableKernelCache 当设置为 False时禁用内核模式缓存。 True maxCacheSize 将 IIS 用户模式缓存大小限制为指定的大小(以 Mb 为单位)。 IIS 根据可用内存调整默认值。 根据经常访问的文件集的大小以及 RAM 或 IIS 进程地址空间的大小,仔细选择值。 0 maxResponseSize 将文件缓存到指定大小。 实际值取决于数据集中最大文件的数量和大小,以及可用内存。 缓存命中率高的话可以减少 CPU 使用量、磁盘访问和相关的延迟。 262144 例如:
<caching enabled="true" enableKernelCache="true"> </caching>
实际上我转移我自己的站点的时候,优化仅仅做到了这一步我就已经放弃了,如果您需要更为详细的优化,您可以参考微软的官方推荐最佳实践:
https://docs.microsoft.com/zh-cn/windows-server/administration/performance-tuning/role/web-server/
以及IIS
文档:
https://docs.microsoft.com/en-us/troubleshoot/developer/webapps/iis/site-behavior-performance/0-byte-file-compression-enabled