上一篇 下一篇 分享链接 返回 返回顶部

香港服务器使用 Windows Server 2012 时,如何优化 Windows Update 策略,避免高峰期更新导致的系统性能下降?

发布人:Minchunlin 发布时间:2025-08-24 09:18 阅读量:629


今年的“618”促销活动的前一周,香港葵涌机房的NOC 屏幕上红点子突然开始闪:IIS 响应时延拉长,队列长度飙升。打开一台前端节点,TiWorker.exe 和 TrustedInstaller.exe 抢占了 70% CPU,磁盘队列像电梯口一样拥挤。——不用想,Windows Update 正在自动装补丁,而时间恰好踩在晚间流量峰前的预热期。

那一晚,我把值守凳子挪到了这排服务器前,调 GPO、限 BITS、切 WSUS、加任务计划、改重启策略、做回滚脚本。第二天上午,业务峰值没再被“更新风暴”击穿。更重要的是,这套方法此后在我们一整批香港节点上落地成了标准。

接下来,我把那夜做过、后来复盘优化过的动作,完整写给你。

场景基线与目标

机房与硬件(示例)

机房:香港,BGP 线路,机内 10GbE,出口 2×10Gbps。

角色拆分:

WEB 前端:IIS 8.0(Windows Server 2012 Standard),Dell R630,2×E5-2680 v4 / 128GB RAM / 4×SATA SSD(RAID10)/ Intel X520 10GbE。

应用层:IIS + .NET 4.7.2。

数据库层:SQL Server 2014(单独维护窗口,本文聚焦 OS 更新)。

时间:以 HKT(UTC+8) 为准。业务峰一般 19:00–01:00 HKT。

痛点

高峰前后自动扫描/下载/安装补丁,TiWorker.exe 占 CPU,I/O 抢占,IIS 请求排队。

一些节点自动重启,负载不均衡。

目标

四层防护思路:源头(WSUS/审批)→ 下载(BITS 限速/时间窗)→ 安装(维护窗口/负载检查)→ 重启(有序可控/无感切换)。

约束:Server 2012(非 R2 也可按本流程),可引入 WSUS;无 SCCM 也能落地;要有回滚。

方案总览(一图胜千言)

四层防护

源头控流:WSUS 分环审批,减少无关补丁;

下行控速:BITS 按时间窗限速(白天低速、凌晨放开);

安装控时:GPO/自动维护锁定“02:00–05:00 HKT”;安装前脚本看负载,不达标就延后;

重启控序:先摘流/Drain,再安装,再健康检查,最后按批次重启;失败立即回滚。

实施步骤

先看现状与数据(务实)

在动任何策略前,我会跑一轮 24 小时观测,抓到“Update 干扰业务”的真实证据。

项目 峰前(18:00–20:00 HKT) 安装期(随机触发) 峰值(20:00–01:00 HKT)
CPU(P95) 42% 78%(有 TiWorker) 65%
磁盘队列长度(P95) 0.7 3.1 1.5
IIS 当前连接数(P95) 3,500 下降/抖动 5,200
P95 响应时间 180 ms > 600 ms 250 ms

这张表是说服产品与老板给维护窗“让道”的最好材料。

1) 源头控流:WSUS + 分环审批

为什么:别让每台机器盲目去公网拉补丁;减少不相关补丁;可分批试水。

拓扑(建议)

在香港同机房上 WSUS 上游(或做一个香港下游 WSUS,上游在总部)。

同机房能够保证更新下载走内网,不占用宝贵的出口带宽。

审批策略(Rings)

Ring 0(Canary):1–2 台前端,先行。

Ring 1(边缘业务):10–20% 前端。

Ring 2(核心):剩余全部。

WSUS 操作要点

“产品与分类”只勾 Windows Server 2012 的 安全更新 / 关键更新;先取消驱动/预览版。

每周三(示例)统一同步 + 清理 + 自动拒绝过期。

按 Ring 分组机器,有节奏地批准。

WSUS 清理脚本(管理机上 PowerShell):

Add-PSSnapin UpdateServices
$wsus = Get-WsusServer -Name "wsus-hk-01" -PortNumber 8530
$cleanup = $wsus.GetCleanupManager()
$cleanup.PerformCleanup()  # 释放磁盘、过期更新等

2) 下行控速:BITS 按时间窗限速

为什么:多数“高峰卡顿”是下载阶段抢带宽/占 I/O。用 BITS 限速,白天慢慢拉,凌晨全速冲。

GPO 路径

计算机配置 → 管理模板 → 网络 → Background Intelligent Transfer Service (BITS)

  • 限制 BITS 后台传输的最大网络带宽:启用
  • 工作时段(例如 08:00–23:00 HKT):512 Kbps–2 Mbps(看内网情况)
  • 非工作时段(例如 23:00–07:59 HKT):不限制

BITS 限速只影响后台传输,正合适 Windows Update 的下载模型。

建议时间表(香港)

时间段 (HKT) 策略
08:00–23:00 BITS 限速 1 Mbps(示例)
23:00–02:00 放宽到 10–50 Mbps(机内网足够时)
02:00–05:00 不限制(维护窗)
05:00–08:00 恢复限速

3) 安装控时:GPO + 自动维护 + 政策键值

A. 指向 WSUS

计算机配置 → 管理模板 → Windows 组件 → Windows Update

指定 Intranet Microsoft 更新服务位置:启用

设置 http://wsus-hk-01:8530(示例)

B. 配置自动更新安装时段

配置自动更新:启用 → 选 4 - 自动下载并按计划安装

计划安装日:0 - 每天(或周四)

计划安装时间:3(即 03:00 HKT)

针对已登录用户不自动重启:启用(RDS/堡垒机尤需)

自动更新检测频率:4 小时

重新计划计划安装:启用(延迟 15 分钟)

Server 2012 的“自动维护”也会调度更新,默认在闲时运行。你可以把维护时间固定到 03:00 HKT,避免“灵活”带来的惊喜。

设置自动维护时间(注册表):

# 维护时间:03:00 HKT
New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\Maintenance" -Force | Out-Null
New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\Maintenance" `
  -Name "MaintenanceStartTime" -PropertyType String -Value "03:00" -Force | Out-Null

(可选)用注册表直配 AU 策略(非首选,给应急用):

$wu = "HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate"
$au = Join-Path $wu "AU"
New-Item $wu -Force | Out-Null
New-Item $au -Force | Out-Null
New-ItemProperty $wu -Name "WUServer" -Value "http://wsus-hk-01:8530" -PropertyType String -Force | Out-Null
New-ItemProperty $wu -Name "WUStatusServer" -Value "http://wsus-hk-01:8530" -PropertyType String -Force | Out-Null
New-ItemProperty $au -Name "AUOptions" -Value 4 -PropertyType DWord -Force | Out-Null            # 4=按计划安装
New-ItemProperty $au -Name "ScheduledInstallDay" -Value 0 -PropertyType DWord -Force | Out-Null  # 每天
New-ItemProperty $au -Name "ScheduledInstallTime" -Value 3 -PropertyType DWord -Force | Out-Null # 03:00
New-ItemProperty $au -Name "NoAutoRebootWithLoggedOnUsers" -Value 1 -PropertyType DWord -Force | Out-Null

4) 安装前的“刹车线”:负载不达标就延后

思路:即便到了 03:00,也可能遇到夜间批处理/备份/长查询。安装前跑一个健康检查,阈值不满足就延期 30 分钟再试。

PowerShell 脚本(部署到每台,配合计划任务 02:55 运行):

# Check-And-Install-WindowsUpdate.ps1
param(
  [int]$MaxCpuP95 = 60,
  [int]$MaxDiskQLen = 1,
  [int]$MaxIISConn = 2000,
  [int]$RetryMinutes = 30
)

function Get-Metric {
  $cpu = (Get-Counter '\Processor(_Total)\% Processor Time' -SampleInterval 2 -MaxSamples 5).CounterSamples.CookedValue | Measure -Average | % Average
  $dq  = (Get-Counter '\PhysicalDisk(_Total)\Current Disk Queue Length' -SampleInterval 2 -MaxSamples 5).CounterSamples.CookedValue | Measure -Average | % Average
  $iis = (Get-Counter '\Web Service(_Total)\Current Connections' -ErrorAction SilentlyContinue).CounterSamples.CookedValue | Measure -Average | % Average
  [pscustomobject]@{ CPU=[int]$cpu; DiskQ=[int]$dq; IISConn=[int]$iis }
}

$metric = Get-Metric
Write-Host "CPU=$($metric.CPU) DiskQ=$($metric.DiskQ) IISConn=$($metric.IISConn)"

if($metric.CPU -gt $MaxCpuP95 -or $metric.DiskQ -gt $MaxDiskQLen -or $metric.IISConn -gt $MaxIISConn){
  Write-Warning "Load too high, deferring update $RetryMinutes minutes."
  Start-Sleep -Seconds ($RetryMinutes*60)
}

# 使用 PSWindowsUpdate(建议装 WMF5.1 后)
if(-not (Get-Module -ListAvailable PSWindowsUpdate)){
  Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
  Set-PSRepository -Name "PSGallery" -InstallationPolicy Trusted
  Install-Module PSWindowsUpdate -Force
}

# 只从 WSUS 安装已批准更新;拒绝驱动类;自动接受 EULA;不自动重启(重启交由 drain 逻辑)
Import-Module PSWindowsUpdate
Get-WindowsUpdate -MicrosoftUpdate -Category 'SecurityUpdates','CriticalUpdates' -NotCategory 'Drivers' | `
  Out-File "C:\Windows\Logs\WU-$(Get-Date -Format yyyyMMdd-HHmm).log"

Install-WindowsUpdate -MicrosoftUpdate -Category 'SecurityUpdates','CriticalUpdates' `
  -NotCategory 'Drivers' -AcceptAll -IgnoreReboot -WhatIf:$false -Verbose

注意:Server 2012 默认 PowerShell 版本较老,建议先上 WMF 5.1,TLS1.2 打开后安装 PSGallery 模块更顺滑。如受限,可把 PSWindowsUpdate 离线拷贝上去导入。

计划任务建议

  • 02:55 运行 Check-And-Install-WindowsUpdate.ps1
  • 03:30 再次运行(兜底)
  • 04:30 检查是否需要重启,按批次重启

5) 重启控序:先摘流,再重启,再拉起

对无状态前端来说,重启不可怕,失控重启才可怕。

IIS 前端批次重启流程

摘流:NGINX/SLB 上把某批机器权重调 0 或移出池;或在本机 netsh http add iplisten 做本地阻断(简化法是 app_offline.htm + 健康探针失败)

安装并重启(或安装后单独判定是否需要重启)

应用预热:IIS Application Initialization 打开,Preload Enabled,预热 URL 成功后再入池

健康检查通过再换下一批

检测是否需要重启:

# 需要重启?
(Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired") -ne $null

6) 安全回滚(必须有)

列出更新包:

dism /Online /Get-Packages /Format:Table | more

卸载指定 KB(静默,无重启):

wusa /uninstall /kb:5034123 /quiet /norestart

重启后验证:再次 dism /Online /Get-Packages,并核查应用日志与合规扫描。

7) 没有 WSUS / 只有“独服几台”的轻量做法

如果短期内没法上 WSUS,至少把下载/安装/重启三件事“掐点”:

  • BITS 限速(见第 2 步)
  • GPO 设定安装窗口(见第 3 步)
  • 任务计划 + 负载脚本(见第 4 步)
  • sconfig(Server Core):sconfig → 选择 5) Windows Update → 设为“仅下载,手动安装”或“计划安装 03:00”。

配置清单(一页总览)

GPO 建议矩阵

策略项 路径 推荐值
指定 WSUS 计算机配置 → 管理模板 → Windows Update http://wsus-hk-01:8530
配置自动更新 同上 4 - 自动下载并按计划安装03:00
针对已登录用户不自动重启 同上 启用(RDS/堡垒机 必须
自动更新检测频率 同上 4 小时
重新计划安装 同上 启用,15 分钟
BITS 限速 计算机配置 → 管理模板 → 网络 → BITS 白天 1 Mbps;凌晨不限
自动维护时间 注册表 03:00

批次与窗口

组别 覆盖比例 安装窗口(HKT) 重启策略
Ring 0 1–2 台 周三 02:00–05:00 预热后入池
Ring 1 20% 周四 02:00–05:00 分批
Ring 2 其余 周五 02:00–05:00 分批

真实落地后的对比数据

指标 优化前 优化后(连续 3 周)
峰前(18:00–20:00)CPU P95 42% 39%
安装期 CPU P95 78%(随机踩到业务) 47%(固定 02–05 点)
磁盘队列 P95 3.1 0.9
P95 响应时间 600+ ms(抖) 210–240 ms(稳)
异常重启/周 3–5 台 0–1 台(多为人工触发)

线上“坑”与现场解法(都是血泪)

  • 时区踩坑:GPO 安装时段按本机时区解释。香港节点请确认 TimeZone = China Standard Time(HKT 同区,不涉夏令时)。
  • WSUS 在异地:曾让香港节点跨境拉补丁,带宽打满。解决:在香港建下游 WSUS;或者开分发点/Cache。
  • .NET 补丁触发应用池大规模 JIT:导致首波请求慢。解决:IIS Application Initialization+预热线程,在入池前把关键路由跑一遍。
  • PSGallery/TLS:Server 2012 老环境装模块报 TLS 错,装 WMF 5.1、启用 TLS 1.2 再走。
  • 数据库层别乱动:SQL 节点的系统补丁放单独窗口;先跑可用性组/故障转移演练再装。
  • “禁止自动重启”用了个爽:结果长期不重启,堆旧补丁。解决:月度强制维护夜,以批次 drain + 重启收尾。
  • 监控误报:凌晨大版本堆积导致磁盘短时突刺,Zabbix 报红。给维护窗挂抑制规则并记录变更号。

附:快速联机与检测命令

# 立即向 WSUS 报到、检查
wuauclt /detectnow
wuauclt /reportnow

# 查看是否有待重启
Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired"

# 查看被安装/待安装更新(PSWindowsUpdate)
Import-Module PSWindowsUpdate
Get-WindowsUpdate -MicrosoftUpdate

# 仅下载(不装)
Get-WindowsUpdate -Download

# 安装(不重启),只安全/关键更新
Install-WindowsUpdate -MicrosoftUpdate -Category 'SecurityUpdates','CriticalUpdates' -NotCategory 'Drivers' -AcceptAll -IgnoreReboot

政策与版本提醒(务必看)

Windows Server 2012 / 2012 R2 已过主流支持期,如果你在合规环境里运行,请确认是否在 **ESU(扩展安全更新)**或第三方扩展支持计划内。没有支持就别开放公网面。

能迁就迁(我说的是长远计划),但在迁移前这套更新策略能显著降低高峰期被更新拖垮的概率。

写完最后一条计划任务,我在机柜门上敲了两下,当作给它们打个气。凌晨四点,机房风声还是一样,可监控屏幕终于不再像心电图一样颤抖——更新在凌晨安安静静地装好,IIS 应用热起来,健康探针一个个绿回去。第二天晚高峰,客服群里没人再提“偶发卡顿”。
这活儿干完的那一刻,我对“可预期”三个字有了新的敬畏:更新并不可怕,可怕的是它失去边界。把源头、下载、安装、重启四条边界划清,系统就不会在你最需要它的时候掉链子。

清单(拿走就能干)

  •  上 WSUS(或下游 WSUS 在香港)
  •  只批“安全/关键”分类,分 Ring 批准
  •  GPO:03:00 HKT 安装;不对登录用户强制重启
  •  BITS:白天限速,凌晨放开
  •  02:55 运行负载检查脚本,负载高则延后
  •  批次摘流→安装→预热→入池→下一批
  •  回滚脚本 wusa /uninstall /kb:xxxxx /quiet /norestart
  •  监控抑制 + 变更登记

如果你现在正坐在香港机房的冷通道里,愿这套做法能让你今晚比我那晚更轻松一点。需要,我也可以把上面的脚本和 GPO 模板再按你的环境改一版。

目录结构
全文