2015-07-20 25 views
5

Aramam gereken birkaç yüz bin URL’ye sahibim. Bunlar, bunları işleyecek ve tabloya durum kodu yazacak bir uygulama sunucusuna yapılan çağrılardır. Bir yanıt (başarısızlık/başarısızlık) beklemek zorunda değilim, sadece sunucu isteği aldı. Aynı anda kaç eşzamanlı iş yapılabileceğini de belirtmek istiyorum.Listeden eşzamansız olarak birçok URL'yi nasıl arayabilirim

Şimdiye kadar elde ettiğim, temelde birisinin başkalarının benzer bir şey yapma girişimi, yalnızca url çağrılarıyla değil. Metin dosyası, her URL'yi kendi satırında içerir. url şöyle görünür:

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

Ve kod:

$maxConcurrentJobs = 10 
$content = Get-Content -Path "C:\Temp\urls.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 
} 

yaşıyorum sorunlar o "iş" başına 2 hataları veriyor ve neden emin değilim olmasıdır. URL dizisini $ döktüğümde içerik iyi görünüyor ve Invoke-WebRequest'i tek tek çalıştırdığımda hatasız çalışıyorlar.

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 

Herhangi bir yardım veya alternatif uygulama takdir edilecektir. Ben powershell kullanarak değil, ama ben Windows 7 Masaüstü veya Windows 2008 R2 sunucuları ile sınırlı ve ağ gecikmeleri kısmak için url içinde localhost kullanarak sunucu üzerinde son komut çalıştırıyor olabilir.

cevap

7

İşlerle birlikte, her yeni İş'in yeni bir süreç oluşturması nedeniyle çok fazla yüke maruz kalırsınız.

Runspaces kullanın! bağlantılı ServerFault yayında belirtildiği gibi

$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) 
} 

, ayrıca temelde bu mükemmel çalışıyor yukarıdaki

+0

yapar Invoke-Parallel gibi, daha genel bir çözüm kullanabilirsiniz. Teşekkür ederim! – trueimage

+0

@ mathias-r-jessen aslında, senkronize olmayan bir şekilde çalışan bir yanıt kontrolüne koymanın herhangi bir yolu var mı? Bu uygulamada eşzamanlı işler sınırı, sadece tüm URL'leri çağırdığı için hiçbir şey yapmaz. En az 200 kodu aldığından emin olmalıyım, eğer uygulama sunucusu bağlantıyı reddediyorsa işlenmeyecek. – trueimage

+0

@trueimage "Yanıt beklemem gerekmiyor" dediğinizi sanmıştım :) Bu, onları yanıtlanıncaya kadar yanıt almak için biraz karmaşık hale getirir, ancak evet, yapılabilir. –

İlgili konular