HTTP Expect继续表现

时间:2015-02-28 17:14:33

标签: c# performance http iis http-headers

在一些互联网资源中,我已经看到一般建议禁用发送Expect:100-continue HTTP标头,以便在客户端实际上不会发送大型主体时提高性能。

然而,测试以下代码表明,发送标题会使整体时间平均减少约50毫秒。

var hc = new HttpClient();
hc.DefaultRequestHeaders.ExpectContinue = ?;
hc.BaseAddress = new Uri("http://XXX/api/");
var r = new HttpRequestMessage(HttpMethod.Post, new Uri("YYY", UriKind.Relative))
{
    Content = new StringContent("{}", Encoding.UTF8, @"application/json")
};


var tt = hc.SendAsync(r).Result;
tt.Content.ReadAsStringAsync().Result.Dump();
hc.Dispose();

以下是使用Expect:100-continue

的请求的WireShark转储
  1 0.000000000    ss.ss.ss.176          dd.dd.dd.150         TCP      66     54515→80 [SYN] Seq=0 Win=8192 Len=0 MSS=1260 WS=4 SACK_PERM=1
  2 0.342137000    dd.dd.dd.150         ss.ss.ss.176          TCP      66     80→54515 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1380 WS=1 SACK_PERM=1
  3 0.342687000    ss.ss.ss.176          dd.dd.dd.150         TCP      54     54515→80 [ACK] Seq=1 Ack=1 Win=66780 Len=0
  4 *REF*          ss.ss.ss.176          dd.dd.dd.150         HTTP     272    POST /XXX/api/YYY HTTP/1.1 
  5 0.361158000    dd.dd.dd.150         ss.ss.ss.176          HTTP     79     HTTP/1.1 100 Continue 
  6 0.361846000    ss.ss.ss.176          dd.dd.dd.150         TCP      56     54515→80 [PSH, ACK] Seq=219 Ack=26 Win=66752 Len=2
  7 0.705497000    dd.dd.dd.150         ss.ss.ss.176          HTTP     461    HTTP/1.1 200 OK  (application/json)
  8 0.726029000    ss.ss.ss.176          dd.dd.dd.150         TCP      54     54515→80 [FIN, ACK] Seq=221 Ack=433 Win=66348 Len=0
  9 1.067923000    dd.dd.dd.150         ss.ss.ss.176          TCP      54     80→54515 [FIN, ACK] Seq=433 Ack=222 Win=65535 Len=0
 10 1.068466000    ss.ss.ss.176          dd.dd.dd.150         TCP      54     54515→80 [ACK] Seq=222 Ack=434 Win=66348 Len=0

没有标题的相同请求:

 11 9.300455000    ss.ss.ss.176          dd.dd.dd.150         TCP      66     54516→80 [SYN] Seq=0 Win=8192 Len=0 MSS=1260 WS=4 SACK_PERM=1
 12 9.640626000    dd.dd.dd.150         ss.ss.ss.176          TCP      66     80→54516 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1380 WS=1 SACK_PERM=1
 13 9.641393000    ss.ss.ss.176          dd.dd.dd.150         TCP      54     54516→80 [ACK] Seq=1 Ack=1 Win=66780 Len=0
 14 *REF*          ss.ss.ss.176          dd.dd.dd.150         HTTP     250    POST /XXX/api/YYY HTTP/1.1 
 15 0.406794000    dd.dd.dd.150         ss.ss.ss.176          TCP      54     80→54516 [ACK] Seq=1 Ack=197 Win=65535 Len=0
 16 0.406963000    ss.ss.ss.176          dd.dd.dd.150         TCP      56     54516→80 [PSH, ACK] Seq=197 Ack=1 Win=66780 Len=2
 17 0.749589000    dd.dd.dd.150         ss.ss.ss.176          HTTP     461    HTTP/1.1 200 OK  (application/json)
 18 0.769053000    ss.ss.ss.176          dd.dd.dd.150         TCP      54     54516→80 [FIN, ACK] Seq=199 Ack=408 Win=66372 Len=0
 19 1.109276000    dd.dd.dd.150         ss.ss.ss.176          TCP      54     80→54516 [FIN, ACK] Seq=408 Ack=200 Win=65535 Len=0
 20 1.109742000    ss.ss.ss.176          dd.dd.dd.150         TCP      54     54516→80 [ACK] Seq=200 Ack=409 Win=66372 Len=0

IIS 7.5,IIS 8.0收到了相同的结果

问题是:

  1. 当理论上相反的情况发生时,是什么让Expect标题的请求执行得更快?
  2. POST请求的主体是否总是在一个单独的TCP数据包内(我只查看了几个样本,这是真的)?这里我的意思是为什么转储中第14行的TCP数据包不包含在第16行的TCP数据包中发送的数据(POST主体)?

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题(延迟约50毫秒)。我猜这是HttpClient .NET Framework实现中的错误。

我使用.NET Core 2.1进行了一些测试,并且能够删除Continue消息而不会降低性能。