2015-12-10 10 views
11

Ho il seguente codice che ho di benchmark con jMeter e ottenere circa 3000 richiesta per la seconda sulla mia macchina localhost (la await manca intenzionalmente per eseguire in modo sincrono):Benchmarking ASP.NET richieste simultanee risultati poveri

public async Task<HttpResponseMessage> Get() 
{ 
    var resp = new HttpResponseMessage(HttpStatusCode.OK); 
    resp.Content = new StringContent(Thread.CurrentThread.ManagedThreadId.ToString(), Encoding.UTF8, "text/plain"); 
    return resp; 
} 

il problema è che quando sospendo la richiesta per un secondo come qui di seguito, per qualche ragione il volume è fino a 10 richieste al secondo per ogni processo w3wp.exe (nuovamente il await manca intenzionalmente per eseguire sincrono):

public async Task<HttpResponseMessage> Get() 
    { 
     Task.Delay(1000).Wait(); 
     var resp = new HttpResponseMessage(HttpStatusCode.OK); 
     resp.Content = new StringContent(Thread.CurrentThread.ManagedThreadId.ToString(), Encoding.UTF8, "text/plain"); 
     return resp; 
    } 

Anche quando faccio uso await non v'è alcuna differenza e le 10 richieste al secondo non migliora affatto:

public async Task<HttpResponseMessage> Get() 
{ 
    await Task.Delay(1000); 
    var resp = new HttpResponseMessage(HttpStatusCode.OK); 
    resp.Content = new StringContent(Thread.CurrentThread.ManagedThreadId.ToString(), Encoding.UTF8, "text/plain"); 
    return resp; 
} 

Ho provato tutte le impostazioni di configurazione e niente rende ogni cambiamento a tutti: `

web.config

<system.net> 
    <connectionManagement> 
     <add address="*" maxconnection="65400" /> 
    </connectionManagement> 
    </system.net> 

aspnet.co nfig

<system.web> 
    <applicationPool 
     maxConcurrentThreadsPerCPU="100" /> 
    </system.web> 

machine.config

<processModel 
autoConfig="false" 
memoryLimit="70" 
maxWorkerThreads="100" 
maxIoThreads="100" /> 

Le configurazioni sono impostate per x86 e x64

ho 32 giga di mem e 4 core fisici, Windows 10

La CPU non supera il 10% di carico quando benching le 10 richieste al secondo.

Il codice sopra riportato utilizza l'API WEB, ma ovviamente riproduco gli stessi risultati utilizzando un gestore HTTP.

+3

Utilizzando un singolo server web di uso generale un'applicazione ASP.NET ben progettata tratterà circa 300 req/s dell'interazione utente reale. I sistemi scarsamente architetti iniziano a vedere quegli zeri scomparire. Per aumentare il throughput su un singolo server Windows che si desidera utilizzare utilizzando "web gardens". In generale il collo di bottiglia non è il tuo server web ma lo stato condiviso (ad es. Il tuo database). –

+0

@ChrisMarisic Io uso un web garden – realPro

+1

10 req/s per una durata di esecuzione di una richiesta di 1 secondo sembra abbastanza normale con qualsiasi tecnologia. Ed è anche normale che la CPU non venga utilizzata (richiede solo l'attesa senza consumare alcuna elaborazione). Cosa ti aspetti? –

risposta

2

Ecco una possibile comprensione. Uno per investigare, comunque.

Task.Delay() crea una nuova attività, il cui lavoro è di mettere in pausa. Se ho capito bene, spesso le attività vengono inviate al pool di lavoro .Net, che ha una dimensione limitata. (È possibile verificare con ThreadPool.GetMaxThreads) Quando si tenta di inserire troppo, il codice eseguirà il backup in attesa che il pool di thread abbia spazio.

Quindi supponiamo di disporre di un pool di thread di dimensioni 40. Dopo aver inviato 40 attività, tutte in attesa di un secondo, il pool di thread è al massimo. Il tuo collo di bottiglia sarebbero le attività, gommando il pool di thread, non dando spazio.

Normalmente, attività che fanno costose query di database di tipo IO o file di controllo di resa di IO mentre aspettano che il lavoro venga eseguito. Mi chiedo se Task.Delay è più "appiccicoso".

Provare a scambiare Task.Delay() per System.Threading.Thread.Sleep() e vedere se questo modifica qualcosa.

+0

L'utilizzo di System.Threading.Thread.Sleep() ha interrotto ulteriormente le richieste al secondo fino a 8 richieste al secondo. – realPro

1

So che per Windows 8 esiste un limite massimo di connessioni simultanee pari a 10 per impedire alle persone che tentano di utilizzare i sistemi operativi consumer per eseguire carichi di lavoro del server. Non vedo alcun motivo per cui Windows 10 sarebbe diverso.

http://blogs.iis.net/owscott/windows-8-iis-8-concurrent-requests-limit

+0

Sì, ho visto anche questo post e così ho installato il server 2016 per eseguire i test, ma il comportamento non è cambiato in alcun modo. – realPro