我遇到一个奇怪的问题,我们的脚本服务器被重载并耗尽了资源。我们有一个脚本可以将数据从一个位置复制到另一个位置,这是在一个包含超过200行文本的大型输入文件中定义的,格式为“源路径,目标路径”。
我们现在正试图扼杀我们一次性最大限度的工作,我认为它运作良好。但是由于某种原因,当输入文件包含超过94行时,我们仍然在服务器上耗尽资源。经过一些测试后,这一点变得明显。
我们尝试将PowerShell 4.0的Windows 2008 R2服务器升级到4个处理器和8 GB RAM,但没有运气。所以我认为我的限制不按设计工作。
错误代码:
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
}
我在这里遗漏了什么吗?谢谢你的帮助。
答案 0 :(得分:1)
您正在使用后台作业,这些作业实际上在本地计算机上的远程会话中运行。根据会话配置中设置的设置,远程会话是有意限制的资源。您可以使用
检查当前设置Get-PSSessionConfiguration
并调整设置以增加会话的可用资源
Set-PSSessionConfiguration
您可能需要进行一些测试,以确切确定您要达到的资源限制,以及需要对此特定应用程序进行哪些调整才能正常工作。
答案 1 :(得分:1)
通过将远程会话的MaxMemoryPerShellMB扩展为1GB到2 GB来解决问题,如here所述。请记住,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