Регулировка задания PowerShell блокирует сервер

У меня возникла странная проблема с перегрузкой нашего сервера сценариев и нехваткой ресурсов. У нас есть сценарий, который копирует данные из одного места в другое, это определено в большом входном файле, который содержит более 200 строк текста в формате «Исходный путь, путь назначения».

Сейчас мы пытаемся ограничить максимальное количество заданий, которые мы запускаем одновременно, и я думаю, что это работает нормально. Но по той или иной причине у нас все еще не хватает ресурсов на сервере, когда входной файл содержит более 94 строк. Это стало очевидно после некоторых испытаний.

Мы попытались обновить наш сервер Windows 2008 R2 с PowerShell 4.0 до 4 процессоров и 8 ГБ оперативной памяти, но безуспешно. Поэтому я предполагаю, что мой дроссель не работает так, как задумано.

Код ошибки:

Insufficient system resources exist to complete the requested service. 

Код:

$MaxThreads = 4
$FunctionFeed = Import-Csv -Path $File -Delimiter ',' -Header 'Source', 'Destination'
$Jobs=@()

Function Wait-MaxRunningJobs {
    Param (
        $Name,
        [Int]$MaxThreads
    )
    Process {
        $Running = @($Name | where State -eq Running)
        while ($Running.Count -ge $MaxThreads) {
            $Finished = Wait-Job -Job $Name -Any
            $Running = @($Name | where State -eq Running)
        }
    }
}

$ScriptBlock = {
    Try {
        Robocopy.exe $Using:Line.Source $Using:Line.Destination $Using:Line.File /MIR /Z /R:3 /W:15 /NP /MT:8 | Out-File $Using:LogFile

        [PSCustomObject]@{
            Source = if ($Using:Line.Source) {$Using:Line.Source} else {'NA'}
            Target = if ($Using:Line.Destination) {$Using:Line.Destination} else {'NA'}
        }
    }
    Catch {
        "Robocopy | ERROR: $($Error[0].Exception.Message)" | 
            Out-File -LiteralPath $Using:LogFile
        throw $($Error[0].Exception.Message)
    }
}

ForEach ($Line in $FunctionFeed) {
    $LogParams = @{
        LogFolder  = $LogFolder
        Name       = $Line.Destination + '.log'
        Date       = 'ScriptStartTime'
        Unique     = $True
    }
    $LogFile = New-LogFileNameHC @LogParams
    ' ' >> $LogFile # Avoid not being able to write to log

    $Jobs += Start-Job -Name RoboCopy -ScriptBlock $ScriptBlock
    Wait-MaxRunningJobs -Name $Jobs -MaxThreads $MaxThreads
}

if ($Jobs) {
    Wait-Job -Job $Jobs
    $JobResults = $Jobs | Receive-Job
}

Я что-то упустил здесь? Спасибо за помощь.


person DarkLite1    schedule 10.04.2015    source источник
comment
Вы не можете открыть удаленный сеанс на исходном или целевом сервере и запустить задания с этого хоста вместо того, чтобы запускать его на своем центральном сервере?   -  person Loïc MICHEL    schedule 10.04.2015
comment
Это было бы сложно, так как не у всех включен PS-Remoting, а у некоторых все еще Win Srv 2003. Главный вопрос здесь заключается в том, почему дроссель не работает для заданий и почему система может быть перегружена, когда выполняется только 4 задания. сразу?   -  person DarkLite1    schedule 10.04.2015
comment
вы выполняете 4 одновременных задания robocopy, этого может быть достаточно, чтобы объяснить проблему... если у них есть общий источник или место назначения   -  person Loïc MICHEL    schedule 10.04.2015
comment
Почему вы вообще определили для этого отдельную функцию? Вы просто усложняете ситуацию. Почему бы просто не проверить количество запущенных заданий и не запустить следующее, если оно ниже порогового значения?   -  person arco444    schedule 10.04.2015
comment
@arco444 arco444 Потому что функция находится в файле модуля, и я часто ее использую. Я просто скопировал это здесь для точности.   -  person DarkLite1    schedule 10.04.2015
comment
@Kayasax Но ошибка исходит не от Robocopy, потому что тогда я бы увидел «Robocopy | ... сообщение об ошибке в моих журналах. Исходный путь действительно часто один и тот же, но путь назначения отличается. Почему это работает для первых 96 рабочих мест, но не для всех?   -  person DarkLite1    schedule 10.04.2015
comment
@ DarkLite1 Я не уверен в твоем последнем предположении. Я предполагаю, что вы достигаете аппаратного или программного ограничения здесь   -  person Loïc MICHEL    schedule 10.04.2015
comment
Я попробую это, чтобы увидеть, имеет ли это значение.   -  person DarkLite1    schedule 10.04.2015


Ответы (2)


Вы используете фоновые задания, которые на самом деле выполняются в удаленных сеансах на локальном компьютере. Удаленные сеансы намеренно ограничиваются ресурсами в соответствии с настройками, установленными в конфигурации сеанса. Вы можете проверить текущие настройки с помощью

Get-PSSessionConfiguration

И настройте параметры, чтобы увеличить ресурсы, доступные для сеансов с

Set-PSSessionConfiguration

Возможно, вам придется провести некоторое тестирование, чтобы точно определить, какой предел ресурсов вы достигаете, и какие корректировки необходимо внести для работы этого конкретного приложения.

person mjolinor    schedule 10.04.2015
comment
Спасибо за отзыв mjolinor. Я изменил Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 2048 и Set-Item WSMan:\localhost\Plugin\Microsoft.PowerShell\Quotas\MaxMemoryPerShellMB 2048 и перезапустил WinRM в соответствии со статьей Microsoft. Когда я сейчас проверяю Get-PSSessionConfiguration | ? {$_.PSVersion -EQ '4.0'} | select MaxMemoryPerShellMB, он все еще говорит 1024... Я что-то пропустил? - person DarkLite1; 10.04.2015

Устранена проблема путем увеличения MaxMemoryPerShellMB для удаленных сеансов с 1 ГБ до 2 ГБ, как описано здесь. Имейте в виду, что Start-Job использует удаленный сеанс PowerShell, как уже было указано mjolinor, поэтому эта переменная применима к заданиям PowerShell.

Решение:

# 'System.OutOfMemoryException error message' when running Robocopy and over 94 PowerShell-Jobs:

Get-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB # Default 1024
Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 2048

# Set PowerShell plugins memory from 1 GB to 2 GB
Get-Item WSMan:\localhost\Plugin\Microsoft.PowerShell\Quotas\MaxMemoryPerShellMB # Default 1024
Set-Item WSMan:\localhost\Plugin\Microsoft.PowerShell\Quotas\MaxMemoryPerShellMB 2048

Restart-Service winrm
person DarkLite1    schedule 13.04.2015