2016-08-16 22 views
0

所以我有2個HTTP POST請求,消耗網絡API如下: -C#消耗與多個HTTP POST網頁API請求

using (var client = new HttpClient()) 
{ 
    client.BaseAddress = new Uri("https://your_url.com:8443/"); 
    client.DefaultRequestHeaders.Accept.Clear(); 
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

    // 1st request // 
    var datatobeSent = new ApiSendData() 
    { 
     UserID = "xxx", 
     UserPsw = "yyy", 
     ApiFunc = "zzz", 
     clearData = "x1y1z1" 
    }; 

    HttpResponseMessage response = await client.PostAsJsonAsync("WebApi", datatobeSent); 
    var resultData = await response.Content.ReadAsStringAsync(); 


    #region Extract Secured Data response from WebApi 

    JObject JsonObject = JObject.Parse(resultData); 
    datatobeSent.SecureData = (string)JsonObject["SecureResult"]; 

    #endregion 


    // 2nd request // 
    var datatobeSent2 = new ApiSendData() 
    { 
    UserID = "xxx", 
    UserPsw = "yyy", 
    ApiFunc = "zzz", 
    SecureData = datatobeSent.SecureData 
    }; 

    HttpResponseMessage response2 = await client.PostAsJsonAsync("WebApi", datatobeSent2); 
    var resultData2 = await response2.Content.ReadAsStringAsync(); 

} 

所以現在我需要一些澄清...

1)我的http POST請求是否都是通過相同的SSL會話發送的? 2)如果他們不是,那麼我怎樣才能將這兩者結合起來並通過單個連接/會話發送2個請求?

3)如何提高此代碼的性能?目前100個請求需要11secs來處理和響應。 (我剛剛使用for循環,計數上述2個樣本的100個http post請求)

+0

我相信他們是。據我所知,它們在同一個SSL會話中作爲不同的請求發送。你爲什麼不嘗試使用示例服務器? –

+0

你是什麼樣的服務器? – Philo

+0

託管一個免費託管服務的簡單服務器並測試您的代碼? –

回答

1

它們位於相同的SSL會話和連接上。同一個HttpClient實例共享一些配置和底層TCP連接。因此,您應該重複使用與您的using語句一樣的實例。

我會嘗試通過異步發出帖子請求和處理結果來提高代碼的性能。這裏有一個選項:

創建一個新類來處理這些異步請求

public class WebHelper 
{ 
    public async Task<string> MakePostRequest(HttpClient client, string route, object dataToBeSent) 
    { 
     try{ 
      HttpResponseMessage response = await client.PostAsJsonAsync(route, datatobeSent); 
      string resultData = await response.Content.ReadAsStringAsync(); 
      return resultData; 
     } 
     catch (Exception ex){ 
     return ex.Message; 
    } 
    } 
} 

通知正在使用相同的HttpClient的實例。在主代碼,你可以測試你的表現是這樣的(爲了簡化我們的測試,我只是做POST請求使用相同的參數101次):

//Start time measurement 
List<Task> TaskList = new List<Task>(); 
for (int i = 0; i < 100; i++) 
{ 
    Task postTask = Task.Run(async() => 
    { 
    WebHelper webRequest = new WebHelper(); 
    string response = await webRequest.MakePostRequest(client, "WebApi", dataToBeSent); 
    Console.WriteLine(response); 
    }); 
    TaskList.Add(postTask); 
} 
Task.WaitAll(TaskList.ToArray()); 
//end time measurement 

而只是一個改進代碼:使用嘗試/抓住提出要求!

+0

感謝Forlani。我將檢查異步調用。我正在使用try/catches ..我發佈了一個非常簡單的代碼版本...另一個想到的問題是,我們可以發送多個請求數據obj ...打包爲單個http POST ..然後服務器響應單獨的迴應? – Philo

1

雖然HttpClient的目標是使用相同的Ssl會話和連接,但這不能保證,因爲它依賴於服務器也維護會話和連接。如果服務器放棄它們,HttpClient將透明地重新協商新的連接和會話。

也就是說,雖然連接和ssl會話建立有一些開銷,但它不可能是任何性能問題的根本原因。

鑑於上述代碼的簡單性,我強烈懷疑性能問題不在您的客戶端代碼中,而在您要連接的服務中。

要確定這一點,您需要隔離該服務的性能。

  1. 如果你是服務的所有者,直接執行了線材的性能測試對服務,使用:對於如何做到這一點,取決於你有過該服務的控制級別有幾個選項像https://www.blitz.io/這樣的工具。如果來自blitz.io的100個連續請求需要11秒,那麼您發佈的代碼不是罪魁禍首,因爲服務本身的平均響應時間爲110毫秒。
  2. 如果您不是該服務的所有者,請使用類似Mountebank這樣的工具來創建該服務的線上測試雙重測試,並使用您現有的測試循環。如果使用Mountebank的測試循環執行得很快,那麼您發佈的代碼不是罪魁禍首。 (Mountebank支持https,但您需要擁有密鑰對,或者在客戶端使用自簽名證書並禁用證書驗證。)

值得注意的是,複雜的Web服務需要110ms的響應時間並不少見。您的測試似乎在進行一系列連續的請求 - 一次請求一次 - 大多數Web服務都是針對並行處理來自獨立用戶的許多請求進行優化的。可擴展性挑戰在於我可以同時處理多少個併發用戶,同時還能確保平均響應時間爲110ms。但是,如果只有一個用戶同時使用該服務,它仍然需要〜110ms。

所以 - 甚至可以採取的早期驗證步驟是確定您的循環中100個順序請求的測試是否是您實際性能要求的有效表示,或者是否應該將您的方法並行調用100次看看您是否可以有100個併發用戶訪問您的服務。

+0

感謝您的回覆。我不認爲我會專門說有一個表現問題..至少不是我所知道的......但是當我有空時,我會尋求提高。有一個需要發送多個參數嗎?然後收到單獨的回覆? – Philo

+0

您可以[批量請求](https://blogs.msdn.microsoft.com/webdev/2013/11/01/introducing-batch-support-in-web-api-and-web-api-odata/)但它需要重要的服務器端更新。我認爲在你的情況下這將是困難的,因爲第二個API調用需要第一個響應數據。進一步改進這一點的唯一方法是重新審視整體架構和API設計,以確定是否真的需要將兩者分成兩個請求。 –

+0

非常感謝這些信息。很有幫助。 – Philo