Если вам знакомо то чувство уверенности когда вы знаете что происходит, знаете что всё под контролем, то возможно вам знакомо и чувство когда оказывается что это далеко не так. В этом посте я расскажу о том как я на ровном месте сел в лужу, почему так вышло и какая работа над ошибками была проведена. Речь пойдёт о Quest Foglight и встроенном правиле проверки памяти.
В своей первой статье я рассказал как проходил ввод в эксплуатацию мониторинговой системы Quest Folight у нас в отделе. Пару недель назад, после очередного релиза, начались жалобы на то что один из сервисов забивал память и устраивал проблемы в виде «system out of memory exception» нашим клиентам. Итак мы имеем дело с банальной утечкой памяти. Почему молчит мониторинг, ведь по факту память забивалась постепенно и все пороги срабатывания правила проходились в течении дня? Как минимум два раза мы должны были получить оповещение, но этого не происходило. Давайте попробуем разобраться вместе.
На картинке вы видите правило VMW Virtual Machine Memory Utilization и то что правило охватывает топологию VMWVirtualMachineMemory. Пока что все правильно и ничего не предвещает подвоха.
Теперь взглянем на один из порогов срабатывания. Нас интересует строка "#utilization from $scope.hostMemory#. Scope у нас в данном случае VMWVirtualMachineMemory из предыдущей картинки. Всё ещё никакого подвоха не чувствуется, но он есть.
Если Вы уже поняли в чем дело значит знаете о vCenter куда больше чем я. Где же всё-таки проблема? Проблема нашлась при анализе того что скармливает vCenter в качестве статистики. По этой ссылке можно узнать о разных метриках которые можно извлечь из vCenter. То что мы всё это время использовали оказалось ни чем иным как Active Memory. Если Вам не хочется ходить по ссылкам то вот цитата: «Amount of memory that is actively used, as estimated by VMkernel based on recently touched memory pages.» Те кто уже смеются над этим — правы. Что такое утечка памяти? Утечка памяти она как хомяк, берет себе зернышки да откладывает за щеку, но при этом никаких активных действий с ними не совершает. Это значит что если нагрузка повышается постепенно, а не скачком то наше правило не сработает! Вот почему мы стабильно получали оповещения когда тестировали это правило memtest-ом и не получали ничего при утечке.
Потом мы открыли кейс с поставщиком и получили подтверждение что да, мы правы конечно, но никакой альтернативы получить требуемую информацию из VMware картриджа нет. Нам рекомендовали использовать хост агенты как альтернативу для получения требуемой информации. Уверен что многие никогда не пользовались этой системой мониторинга и не в курсе об абсолютно диком подходе к сбору данных из операционной системы. Никакого механизма импорта или автоматического добавления машин в систему просто нет. Требуется вручную добавлять каждую, тратя в среднем минуты полторы. Стоит ли говорить что несколько сотен виртуалок никто вручную добавлять не хочет, да и потом ведь ещё уследить надо что удалили, а что добавили.
Решением стало несколько скриптов написанных в powershell. Один постоянно проверяет и сравнивает список включенных виртуалок где есть не нулевой IP. Второй подключается уже непосредственно к виртуалкам по WMI и собирает то что требуется. Сразу признаюсь что я не знаток powershell и потому свои скрипты представляю на обзор только в качестве ознакомления — похвастаться нечем. Достаточно упомянуть что освоить powershell jobs я смог далеко не сразу, хотя понимание того что распараллелить нужно было сразу — скрипт последовательно проверявший пару сотен виртуалок занимал минут 10, далеко не лучший способ сбора данных. Теперь эти скрипты собирают мне данные для Foglight-а, а уже в нем я создаю правила и отчеты, хотя можно было делать это прямо в скрипте, но тогда бы не было красивого отображения данных на большом экране.
Вот скрипт сбора данных. Ничего феноменального. Часть пришлось вырезать — там разная специфика именно нашего окружения.
$csv = Import-Csv .Inv.csv #Load inventory
foreach ($server in $csv){
if ($server."Domain Name" -like "*домен*"){
#This limits the number of concurrently running jobs. Set number of jobs and sleep timer here.
While ($(Get-Job -state running).count -ge 50){
Start-Sleep -Milliseconds 250
}
Start-Job -scriptblock {
param($ipAddress, $hostName, $domainName)
$return=@()
$Memory=Get-WmiObject win32_operatingsystem -ComputerName $ipAddress | Foreach {"{0:N2}" -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize)}
$return=New-Object PSObject
$return|Add-Member -MemberType "NoteProperty" -Name "ipAddress" -Value $ipAddress
$return|Add-Member -MemberType "NoteProperty" -Name "memoryUtilization" -Value $Memory
$return|Add-Member -MemberType "NoteProperty" -Name "hostName" -Value $hostName
$return|Add-Member -MemberType "NoteProperty" -Name "domainName" -Value $domainName
if ($error[0]) {
$return|Add-Member -MemberType "NoteProperty" -Name "Error" -Value $error[0]
}
else
{
$return|Add-Member -MemberType "NoteProperty" -Name "Error" -Value "NA"
}
$return
} -ArgumentList ($server."IP Address", $server."VMName".toUpper(), $server."Domain Name".toUpper())
}
}
Get-Job | Wait-Job -Timeout 30
$recievedObject = Get-Job | Receive-Job
Get-Job | Remove-Job -Force
#start building folight observation set
Write-Output "TABLE WMI"
foreach($observation in $recievedObject)
{
Write-Output "START_SAMPLE_PERIOD"
Write-Output "host.String.id = $($observation.hostName).$($observation.domainName)"
Write-Output "ipAddress.String = $($observation.ipAddress)"
Write-Output "physicalMemoryUsed:percent = $($observation.memoryUtilization)"
Write-Output "error.StringObservation.obs =$($observation.Error)"
Write-Output "END_SAMPLE_PERIOD"
}
Write-Output "END_TABLE"
Конструктивная критика приветствуется.
Автор: Roto