Как я могу асинхронно вызывать много URL-адресов из списка

у меня есть несколько сотен тысяч URL, которые мне нужно позвонить. Это вызовы на сервер приложений, который будет их обрабатывать и записывать код состояния в таблицу. Мне не нужно ждать ответа (success/fail), только чтобы сервер получил запрос. Я также хочу указать, сколько параллельных заданий может выполняться одновременно, поскольку я не выяснил, сколько параллельных запросов может обрабатывать tomcat.

вот что у меня есть до сих пор, в основном взятые из чужих попытайтесь сделать что-то подобное, только не с вызовами url. Текстовый файл содержит каждый URL в отдельной строке. Url выглядит следующим образом:

http://webserver:8080/app/mwo/services/create?server=ServerName&e1user=admin&newMWONum=123456&sourceMWONum=0&tagNum=33-A-1B

и код:

$maxConcurrentJobs = 10
$content = Get-Content -Path "C:Tempurls.txt"

foreach ($url in $content) {
    $running = @(Get-Job | Where-Object { $_.State -eq 'Running' })
    if ($running.Count -le $maxConcurrentJobs) {
        Start-Job {
             Invoke-WebRequest -UseBasicParsing -Uri $using:url
        }
    } else {
         $running | Wait-Job -Any
    }
    Get-Job | Receive-Job
}

проблемы у меня есть в том, что он дает 2 ошибки на "работу", и я не уверен, почему. Когда я сбрасываю массив url $content, он выглядит нормально, и когда я запускаю свой Invoke-WebRequest один за другим, они работают без ошибок.

126    Job126          BackgroundJob   Running       True            localhost            ...                
Invalid URI: The hostname could not be parsed.
    + CategoryInfo          : NotSpecified: (:) [Invoke-RestMethod], UriFormatException
    + FullyQualifiedErrorId : System.UriFormatException,Microsoft.PowerShell.Commands.InvokeRestMethodComman 
   d
    + PSComputerName        : localhost

Invalid URI: The hostname could not be parsed.
    + CategoryInfo          : NotSpecified: (:) [Invoke-RestMethod], UriFormatException
    + FullyQualifiedErrorId : System.UriFormatException,Microsoft.PowerShell.Commands.InvokeRestMethodComman 
   d
    + PSComputerName        : localhost

любая помощь или альтернативные реализации будут оценены. Я открыт для использования powershell, но я ограничен рабочими столами Windows 7 или серверами Windows 2008 R2, и я, вероятно, буду запускать окончательный сценарий на самом сервере, используя localhost в url-адресе, чтобы сократить сетевые задержки.

1 ответов


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

использовать пространства выполнения!

$maxConcurrentJobs = 10
$content = Get-Content -Path "C:\Temp\urls.txt"

# Create a runspace pool where $maxConcurrentJobs is the 
# maximum number of runspaces allowed to run concurrently    
$Runspace = [runspacefactory]::CreateRunspacePool(1,$maxConcurrentJobs)

# Open the runspace pool (very important)
$Runspace.Open()

foreach ($url in $content) {
    # Create a new PowerShell instance and tell it to execute in our runspace pool
    $ps = [powershell]::Create()
    $ps.RunspacePool = $Runspace

    # Attach some code to it
    [void]$ps.AddCommand("Invoke-WebRequest").AddParameter("UseBasicParsing",$true).AddParameter("Uri",$url)

    # Begin execution asynchronously (returns immediately)
    [void]$ps.BeginInvoke()

    # Give feedback on how far we are
    Write-Host ("Initiated request for {0}" -f $url)
}

Как отмечено в связанном сообщении ServerFault, вы также можете использовать более общее решение, например Invoke-Parallel, что в основном делает выше