2017-05-16 7 views
2

Ich habe eine Selfhosted-Web-API mit OWIN, und ich habe Mühe auf gleichzeitige Verbindungen. Wenn ich einen Stresstest mit 50 gleichzeitigen get-Ereignissen führe, steigt die Antwortzeit A LOT, auch wenn die Operation ziemlich einfach ist, gebe 200 OK mit der in der uri eingegebenen ID zurück.Web Api 2 OWIN Selfhost behandeln mehrere gleichzeitige Anfragen

Wie kann ich meine Web-API OWIN und API-Controller simultan pro Anfragen ausführen?

Hier ist eine Probe von meinem Projekt:

Startup Klasse

public class Startup 
{ 
    public void Configuration(IAppBuilder appBuilder) 
    { 
     try 
     { 
      appBuilder.UseWelcomePage("/welcome.html"); 
      appBuilder.UseErrorPage(new ErrorPageOptions 
      { 
       ShowExceptionDetails = 
    #if DEBUG 
       true 
    #else 
       false 
    #endif 
      }); 

      Debug.WriteLine($"Setting Web Api Configuration up..."); 
      var apiConfig = ConfigureWebApi(); 
      appBuilder.UseWebApi(new HttpServer(apiConfig)); 
      appBuilder.UseCors(CorsOptions.AllowAll); 

      Debug.WriteLine($"Completed Web Api configuration."); 
     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine($"Failed to complete Web Api setup.", ex); 
      throw; 
     } 
    } 
} 

-Controller

public class TestController : ApiController 
{ 
    public async Task<IHttpActionResult> Get(int id) 
    { 
     return Task<IHttpActionResult>.Factory.StartNew(() => { 
      try 
      { 
       return Ok(id); 
      } 
      catch (Exception ex) 
      { 
       Debug.WriteLine(ex.Message, nameof(Get)); 
       return InternalServerError(); 
      } 
     }); 
    } 
} 

Meine Konsole Inbetriebnahme von Web-api:

public static void Open() 
{ 
    _webApp = WebApp.Start<Startup>(HostAddress); 
    Console.WriteLine($"Host open -> {HostAddress}"); 
} 
+0

Wie machen Sie Ihren Stresstest? Kannst du diesen Code posten? – MichaelDotKnox

+0

Anstatt Factory.StartNew auszuführen, können Sie auch Task.FromResult (Ok (Id)) zurückgeben, das weniger wahrscheinlich blockiert. Nicht sicher, ob das Ihre Probleme verursachen würde. – MichaelDotKnox

+0

Verwenden von Paesslers Webserver Stress Tool, um den Stresstest durchzuführen. Denken Sie daran, stattdessen einen einfachen Client zu erstellen und zu sehen, wie es geht. Danke für den Tipp mit Task.FromResult. – grmihel

Antwort

1

Ihrer api Alle con troller-Methoden werden gleichzeitig ausgeführt, offensichtlich begrenzt durch die Fähigkeiten des Servers, der die API hostet. Das ist eine Funktion des Webservers, ob es IIS oder selbst gehostet ist. Es gibt jedoch Dinge, die Sie tun können, um das zu unterstützen.

Wenn Sie alles asynchron halten, werden Sie die beste Leistung sehen. wenn Sie Controller-Methode zum Beispiel sieht wie folgt aus:

public async Task<IHttpActionResult> Get(int id) 
{ 
    var testObject = await _repository.GetAsync(id); 

    return Ok(testObject); 
} 

und Sie haben ein Repository-Methode, die wie folgt aussieht:

public async Task<TestObject> GetAsync(int id) 
{ 
    using(var connection = new SqlConnection(_connectionString) 
    { 
     // using Dapper 
     return await connection.QuerySingleAsync<TestObject>("sp_GetTestObject", new {Id = id}, commandType = CommandType.StoredProcedure); 
    } 
} 

tun dies der Computer ermöglicht Worker-Threads für die Datenbank zu verwenden I/O, wodurch Verarbeitungsleistung für die Verarbeitung anderer Aufgaben zur Verfügung steht, beispielsweise das Akzeptieren anderer Anfragen an den API-Endpunkt. Jemand wie @ StephenCleary kann wahrscheinlich erklären, was ich sage und/oder korrigieren. @ StephenCleary's blog und Buch sind definitiv eine Lesung wert, asynchrone Programmierung zu verstehen.

Hoffe, dass hilft.

+0

Danke, das ist genau das, was ich gesucht habe. Scheint jetzt so glatt wie möglich zu laufen. – grmihel

Verwandte Themen