云上Windows Server进程级问题排查方式

本来以为这类基础系统问题对于一个IT环境来说排障不会存在太大困难,可惜事与愿违,很多时候恰恰就是这些简单的问题导致了一个重大的故障,笔者在从业过程中也遇到了很多例,在感叹这些IT从业者对基础系统使用知识缺乏的同时,也自省了下,笔者以往都是大张旗鼓的倒腾“私有云”、“虚拟化”、“IOT”、“大数据”却很少在这种细微的问题上输出过有价值的文章。

在使用微软系的一些解决方案中,或者日常使用Windows Server过程,其实基本功非常重要,比如对于进程级的检查,当系统因为某些进程夯住导致系统异常无法动弹时,重启后系统进程现场丢失,那么要如何定位究竟是什么进程导致了系统异常呢?

在Linux里,Atop无疑是最好的选择:

亦或是用dmp(panic产生的文件)来判断当时Linux运行状态:

那么在Windows Server里如何来实现进程级别的追溯?

方式一,SCOM(或Zabbix或其他监控套件):

SCOM是微软System Center 套件中的一个重要大员,笔者从11年研究到16年,也是至今未找到能够与这个解决方案比拟的代替方案,其架构的完整度,ITIL落地性是最高的,可惜非常厚重,以至于没有人有有信心跟耐心去深入研究这个架构,所以我们现在可以看到很多众多从业者造的“轮子”,在SCOM上实现的进程级监控是这样的:

配置监控阈值:

进程级告警:

可惜,SCOM始终太过笨重,在超大型IT架构中可以采用此方案(目前未见到),如果为了一次排障而去部署这套架构实在有点大材小用了,所以这里不展开讲这个方案,对这个方案有兴趣的同学可以看我之前写过的SCOM系列文章来学习,关于监控进程的在此:http://vmcloud.info/?p=379

方式二,PowerShell:

PowerShell是一个比较灵活且在Windows Server平台上兼容性较高的方式,不过要求一定的读写脚本能力,我这里抛砖引玉下:

进程CPU占用情况:

代码语言:javascript
复制
(Get-WMIObject Win32_ComputerSystem).NumberOfLogicalProcessors
(Get-Counter "\Process(*)\% Processor Time").CounterSamples | Select InstanceName, @{ Name = "CPU %"; Expression = { [Decimal]::Round(($_.CookedValue / $CpuCores), 2) } }

进程内存占用情况:

代码语言:javascript
复制
 Get-Process | select *

要实现追溯的目的,那就必须长期驻留跑着,此时需要考虑下如何持续保留:

1、可以采用export-csv来将进程记录到csv中;

2、避免csv被打爆也可以用文件总数或者时间来判断是否是进行清理;

3、一个适当的循环来保证脚本持续运行下去;

如不嫌弃,我写了一个demo可以供大家使用:

代码语言:javascript
复制
function GetProcess ()

{
$filehostname = hostname
$filedatetmp = Get-Date
filedate = filedatetmp.ToString('MM-dd-hh-mm-ss')
cd C:
Dirfilename = "QCloud-TS-filehostname"
Logfilename = "filedate-Log.csv"
TPRs = Test-Path Dirfilename
if (TPRs -eq false) { New-Item -Path $Dirfilename -Type Directory | Out-Null}
$CpuCores = (Get-WMIObject Win32_ComputerSystem).NumberOfLogicalProcessors
(Get-Counter "\Process(*)% Processor Time").CounterSamples | Select InstanceName, @{ Name = "CPU %"; Expression = { [Decimal]::Round((_.CookedValue / CpuCores), 2) } } | Export-Csv -Path ".$Dirfilename$Logfilename" | Out-Null
PathLogfilename = "Path-filedate-Log.csv"
filenums = Get-ChildItem Dirfilename| Measure-Object
Get-Process | select * | Export-Csv -Path ".$Dirfilename$PathLogfilename"
if ($filenums.count -gt 3600)
{
$GDfilename = New-Item -Path ".$Dirfilename$filedate-LogGD" -Type Directory | Out-Null
Move-Item ".$Dirfilename*.csv" ".$Dirfilename$filedate-LogGD" | Out-Null
Move-Item ".$Dirfilename*.txt" ".$Dirfilename$filedate-LogGD" | Out-Null
Write-Host $filedatetmp + "监控文件超过3600份,已归档"
}
Write-Host $filedatetmp + "性能数据已收集,继续运行"
}
while (1)
{
GetProcess
sleep 1
}

通过这种方式可以持续的收集进程情况,当CVM异常时可以及时回溯宕机前的进程占用情况。

方式三:crash dump:

关于Dmp文件我在https://cloud.tencent.com/developer/article/1005517这系列文章中有解释过,这种方式获取系统异常时的进程情况是非常有效的方式,不过成本比较高,其效果如下:

在Windows Server 中panic level不像linux那么细致可以根据阈值调整宕机的灵敏度,所以有时候需要通过必要设置来手动触发crash,具体涉及的注册表如下:

代码语言:javascript
复制
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters
新建一个DWORD键,名称为:CrashOnCtrlScroll,其值为1

重新启动计算机使其生效后,在系统异常时,按住 Ctrl 键,同时按 Scroll Lock 键两次即可触发,不过腾讯云目前还没有在控制台实现键位重定向功能,所以此方式需要提单给后台工程师协助触发。

综合对比来说

方式

轻量

效果(可视化程度)

SCOM/Zabbix

⭐⭐

⭐⭐⭐⭐⭐

PowerShell

⭐⭐⭐⭐

⭐⭐⭐

DMP

⭐⭐

So,建议采用PowerShell在特定的排障场景中制定适合具体case的脚本。

本篇主要讲述如何通过多种方式获取系统异常时进程的状态,具体如何应用,还得靠各位看官的具体实践了,这里就不具体展开讲了。


另外团队招人中,Job List(以下岗位全职、实习均可)

22989-腾讯云系统技术工程师(深圳)

22989-腾讯云运营系统开发工程师(深圳)

22989-腾讯云服务器系统工程师(深圳) 

22989-腾讯云平台服务器硬件系统工程师(深圳)

具体要求请检索:http://hr.tencent.com/position.php

直接投递简历 EMail : StatLi@tencent.com