2016-08-16 23 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