Недавно мне потребовалось проанализировать потребление памяти на терминальном сервере, чтобы оценить вместимость сервера по количеству одновременно работающих пользователей. Филиалы организации достаточно широко разбросаны географически, пользователи подключаются к сайту с базой данных по достаточно слабым каналам, поэтому мы установили клиент "1С: Предприятие" на терминальный сервер в основном филиале. Пользователи со своих клиентских машин через Удаленный рабочий стол работают на сервере, к ним на компьютеры возвращаются только разностные данные по перерисовке картинки рабочего стола сервера и задания печати с сервера на принтер, при обрыве соединения база данных не страдает и сессии к 1С не висят (рассматривалась работа 1С версии 7.7), при восстановлении соединения пользователь возвращается в свою сессиию.
Так как бизнес растет, то потребовалось оценить, сколько пользователей сможет принять сервер. При анализе работы сервера с текущей нагрузкой в течении двух суток при помощи счетчиков производительноти оказалось, что узкое место - это память, остальные параметры (процессорное время, нагрузка сети, использование диска) не поднимались даже до средних значений.
Итак, чтобы собрать данные, сколько же памяти расходует одна пользовательская сессия, я использовал следующий скрипт Power Shell (анализ производился когда на сервере еще оставалась свободная физическая память).
function Get-ProcessWithOwners() { param ( [string]$SearchString = 'name like "%"', [string]$Computer = "." ) $processes = Get-WmiObject Win32_Process -Filter $searchString -ComputerName $Computer $appendedprocesses = foreach ($process in $processes) { Add-Member -MemberType NoteProperty -Name Owner -Value ($process.GetOwner().User) ` -InputObject $process -PassThru } $appendedprocesses | select Name, Handle, Owner, @{Label="VirtualMemory";Expression={[int]($_.VirtualSize)}}, @{Label="PagedMemory";Expression={[int]($_.PageFileUsage)}}, @{Label="WorkingMemory";Expression={[int]($_.WorkingSetSize)}} | Sort-Object -Property Owner } $processes = Get-ProcessWithOwners -Computer ServerName $processes | Format-Table Name, Handle, Owner, @{Label="VirtualMemory (MB)";Expression={[int]($_.VirtualMemory/1MB)}}, @{Label="PagedMemory (MB)";Expression={[int]($_.PagedMemory/1MB)}}, @{Label="TotalMemory (MB)";Expression={[int](($_.VirtualMemory + $_.PagedMemory)/1MB)}}, @{Label="WorkingMemory (MB)";Expression={[int]($_.WorkingMemory/1MB)}} | Out-File ` -FilePath ($env:USERPROFILE + "\My Documents\Processes.txt")
После работы скрипта в папке Мои Документы появился файл Processes.txt с таким содержимым:
Name Owner TotalMemory (MB) WorkingMemory (MB) ---- ----- ---------------- ------------------ System Idle Process 0 0 svchost.exe LOCAL SERVICE 21 3 svchost.exe LOCAL SERVICE 21 3 svchost.exe LOCAL SERVICE 37 5 svchost.exe LOCAL SERVICE 14 2 alg.exe LOCAL SERVICE 29 4 logon.scr LOCAL SERVICE 38 2 wmiprvse.exe NETWORK SERVICE 73 16 msdtc.exe NETWORK SERVICE 37 7 svchost.exe NETWORK SERVICE 67 7 svchost.exe NETWORK SERVICE 37 6 explorer.exe user01 97 14 egui.exe user01 76 5 wscript.exe user01 104 14 ctfmon.exe user01 37 3 rdpclip.exe user01 61 5 ctfmon.exe user01 37 3 splwow64.exe user01 64 5 1cv8.exe user01 421 145 ctfmon.exe user02 37 3 ctfmon.exe user02 37 3 scrnsave.scr user02 31 2 explorer.exe user02 92 13 rdpclip.exe user02 60 5 wscript.exe user02 104 14 egui.exe user02 76 5 splwow64.exe user02 50 4 1cv8.exe user02 413 139
Из этого отрывка таблички видно, какие процессы запущены у каждого пользователя, работающего на сервере, сколько памяти потребляет каждый процесс. Если просуммировать параметр Working Memory у каждого пользователя и усреднить полученные данные, то можно вычислить среднее значение физической памяти, необходимое для работы одного среднестатистического пользователя. Если сложить параметр Working Memory у служебных пользователей SYSTEM, LOCAL SERVICE и NETWORK SERVICE, то можно получить значение физической памяти, необходимое для работы операционной системы. Параметр Total Memory отвечает за объем использования памяти с учетом файла подкачки - виртуальная память. При больших разрывах в значениях между Working Memory и Total Memory пользователи начинают ощущать замедление в работе терминального сервера, так как производится частое обращение к диску для записи и считывания данных, не поместившихся в физическую память. Нормальное соотношение физической памяти к виртуальной памяти (физическая память + файл подкачки) равно от 1:2 до 1:3.
После подсчетов, усреднения и округления получилось, что один пользователь 1С потребляет в среднем 200 МБ физической памяти или 600 МБ виртуальной памяти, система потребляет 600 МБ физической памяти или 4000 МБ виртуальной памяти. Вместительность сервера на Windows Server 2003 64bit с 16 ГБ установленной ОЗУ равна: (16384 МБ [установлено] - 600 МБ [система]) / 200 МБ [пользователь] = 78 пользователей. То есть при использовании на терминальном сервере только приложения 1С одновременно могут работать 78 человек, не ощущая особых задержек в работе по причине нехватки памяти.
Если же на сервере будут запускаться другие программы, то данные нужно будет скорректировать. Например, при использовании на терминальном сервере программы MS Office потребуется 513 МБ ОЗУ для каждого клиента (значение взято из системных требований к MS Office и не измерялось на практике). То есть вместительность сервера Windows Server 2003 64bit с 16 ГБ установленной ОЗУ равна: (16384 МБ [установлено] - 600 МБ [система]) / (200 МБ [1C] + 512 МБ [MS Office]) [пользователь] = 22 пользователей.
Как видно, чтобы организовать работу 1С в компании с мелкими филиалами, разбросанными по всей стране, потребуются значительные вложения в инфраструктуру:
- или в серверы при организации работы в терминальном режиме при слабых линиях связи,
- или в скорость и стабильность линий связи от филиалов к центральному офису, где расположена база данных, при установке клиентов 1С непосредственно в филиалах.
Все заметки о службе терминалов в моем блоге можно найти по тегу RDS.