.NET HttpClient不会为并行请求重用tcp连接

时间:2016-06-15 20:07:22

标签: .net

我有以下nodejs服务器。它只在HTTP上提供json,并在建立新的tcp连接时记录:

var http = require('http');

var response = [{"name":"Alice"},{"name":"Bob"}];
var count=0;
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/json'});
  res.end(JSON.stringify(response));
}).on('connection', function(socket) {
  console.log('new TCP stream is established ' + count)
  count++;
  socket.setTimeout(5000);
}).listen(5000);

我使用以下C#程序查询此服务器,该程序启动10个http请求并且不等待他们的响应

//to check connection reuse across processes
Console.WriteLine("ProcessID " + Process.GetCurrentProcess().Id);

HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://mypc.domain.com:5000");

for (int i = 0; i < 10; i++)
{
    var result = client.GetAsync("/"); // or client.GetAsync("/").Result
    Console.Writeline("requested " + i);
}

当我运行它时,我看到以下输出:

建立新的TCP流0


建立新的TCP流9

它创建了10个tcp连接。

现在我快速连续运行C#程序(在服务器上设置的5秒超时)。我没有看到任何新的TCP连接被创建。 10个新请求重用上一次运行的TCP连接。

有没有办法让HttpClient只为并行请求创建和重用一个TCP连接? 是否可以在同一个TCP连接上发出并行请求?

1 个答案:

答案 0 :(得分:3)

由于您极快地启动请求,因此它们都需要新连接。不应该有任何重用(不保证但可能)。

  

现在我快速连续运行C#程序了

跨进程没有连接重用。这里没有重用。但是你以为你发现这是真的 - 事实并非如此。我不熟悉节点。

  

有没有办法让HttpClient只为并行请求创建和重用一个TCP连接?

TCP连接只能通过流水线并行运行多个HTTP请求,这不是一种可靠的优化方法。我想你可以用.NET打开HTTP流水线。

  

是否可以在同一个TCP连接上发出并行请求?

是的,通过流水线操作。

我认为流水线技术不一定是您的目标,因为它也会将响应序列化。

你可能应该依赖HTTP keep alive,我认为默认情况下是这样。存在10个TCP连接没有坏处。如果您稍微更改程序,您将看到100%重用:

for (int i = 0; i < 10; i++)
{
    var result = client.GetAsync("/").Result; //Wait here
    Console.Writeline("requested " + i);
}

或者:

while (true) {
    for (int i = 0; i < 10; i++)
    {
        var result = client.GetAsync("/"); //NO waiting here
        Console.Writeline("requested " + i);
    }
    Thread.Sleep(1000); //wait/hope for requests to finish
}