2017-05-16 49 views
2

我有一個使用OWIN自支持的web API,而且我似乎很難在併發連接上。當我使用50個併發獲取事件進行壓力測試時,響應時間正在增加A LOT,即使操作非常簡單,使用在uri中鍵入的id返回200 OK。Web Api 2 OWIN Selfhost處理多個併發請求

如何我的網頁api OWIN和api控制器每個請求運行simultanious?

這裏是我的項目的一個樣本:

啓動類

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; 
     } 
    } 
} 

控制器

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(); 
      } 
     }); 
    } 
} 

我的控制檯Web API的啓動:

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

你最近怎麼樣做壓力測試?你可以發佈該代碼嗎? – MichaelDotKnox

+0

另外,不要使用Factory.StartNew,而是返回不太可能阻塞的Task.FromResult(Ok(Id))。不知道這是否會導致你的問題。 – MichaelDotKnox

+0

使用Paessler的Webserver Stress工具來執行壓力測試。思考如何創建一個簡單的客戶端,看看它是如何發展的。感謝與Task.FromResult提示。 – grmihel

回答

1

你的所有的API CON troller方法將同時運行,顯然受託管api的服務器的功能限制。這是Web服務器的功能,無論是IIS還是自己託管。然而,你可以做些事情來幫助這一點。

如果您一直保持一切異步,您將看到最佳性能。例如,如果你的控制器方法是這樣的:

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

    return Ok(testObject); 
} 

,你有一個看起來像這樣的庫方法:

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

這樣做可以讓計算機使用工作線程數據庫I/O,釋放處理能力來處理其他任務,例如接受對API端點的其他請求。像@StephenCleary這樣的人可能可以闡述我說的和/或糾正它。 @ StephenCleary的blog和book絕對值得一讀,以瞭解異步編程。

希望有所幫助。

+0

謝謝,這正是我期待的東西。似乎現在儘可能流暢地運行。 – grmihel