167人参与 • 2024-08-01 • Access
expect: 100-continue
头部字段最早在http/1.1规范中引入。其主要目的是在客户端发送大请求主体(如文件上传)之前,确保服务器能够处理该请求,从而避免不必要的数据传输。
可以将expect: 100-continue
机制比作一个礼貌的问询:
expect: 100-continue
:
expect: 100-continue
头并等待100 continue响应)。expect: 100-continue
可以确保服务器能够接受这些数据,从而避免在服务器不能处理请求的情况下浪费带宽。虽然expect: 100-continue
在某些情况下依然有用,但现代网络环境和服务器架构的进步使其重要性有所降低:
是否需要使用expect: 100-continue
取决于具体的应用场景:
expect: 100-continue
头可以减少等待时间,优化性能。expect: 100-continue
的机制expect
是一个请求消息头,包含一个期望条件,表示服务器只有在满足此期望条件的情况下才能妥善地处理请求。
规范中只规定了一个期望条件,即 expect: 100-continue
, 对此服务器可以做出如下回应:
100
如果消息头中的期望条件可以得到满足,使得请求可以顺利进行的话,417
(expectation failed) 如果服务器不能满足期望条件的话;也可以是其他任意表示客户端错误的状态码(4xx)。例如,如果请求中 content-length
的值太大的话,可能会遭到服务器的拒绝。常见的浏览器不会发送 expect
消息头,但是其他类型的客户端如 curl 默认会这么做。
客户端发送带有expect: 100-continue
头的请求,服务器在确认可以处理请求后响应100 continue
,然后客户端发送请求主体。如果服务器没有及时响应,客户端将在等待一段时间后继续发送请求主体。这种等待时间会增加请求的总耗时,尤其在长连接中更明显。
http协议中的expect
头字段通常用于通知服务器客户端期望的特定行为。默认情况下,客户端可能会自动添加expect: 100-continue
头,这意味着在发送大数据请求主体(例如文件上传)之前,客户端希望服务器先确认请求是否会被接受。
这种机制可以有效避免不必要的数据传输,但在使用长连接时,客户端等待服务器响应100 continue
可能导致显著的延迟。如果服务器未及时响应,客户端将等待一个超时时间,然后再发送请求主体,这会增加总体请求耗时。
注意: expect: 100-continue
机制与连接的长短无关。无论是短连接还是长连接,当客户端发送一个包含expect: 100-continue
头的请求时,都会触发同样的机制:客户端在发送请求主体前等待服务器的100 continue
响应。所以在短连接中,expect: 100-continue
头的存在同样会导致客户端在发送请求主体前等待服务器的100 continue
响应。如果服务器的响应不及时或网络延迟较大,这段等待时间会增加整个请求的耗时。
expect
头优化性能目前规范中只规定了 “100-continue” 这一个期望条件: 表示通知接收方客户端要发送一个体积可能很大的消息体,期望收到状态码为100
(continue) 的临时回复。
expect: 100-continue
e.g.比如curl库默认设置, 或者发送大消息体时: 服务器开始检查请求消息头,可能会返回一个状态码为 100
(continue) 的回复来告知客户端继续发送消息体,也可能会返回一个状态码为417
(expectation failed) 的回复来告知对方要求不能得到满足。
# 客户端发送带有 expect 消息头的请求,等服务器回复后再发送消息体。
put /somewhere/fun http/1.1
host: origin.example.com
content-type: video/h264
content-length: 1234567890987
expect: 100-continue
为了避免这种延迟,可以显式设置空的expect
头。这样,客户端会直接发送请求主体,而不等待服务器响应100 continue
。这减少了等待时间,提高了请求的整体速度。
expect
问题解决在实际应用中,我负责将一个使用curl库访问上游接口的系统从原本的短连接改为长连接。我们的初衷是通过长连接减少频繁建立和关闭连接的开销,从而显著降低接口调用的耗时。然而,改为长连接后,监控视图却显示接口调用的平均耗时不降反增。
为了进一步了解问题,我们开始对接口调用过程进行抓包分析。在抓包数据中,我们发现每次发起http请求时,第一跳的请求会出现几百毫秒的延迟。这种延迟在后续请求中并未消失,导致整体耗时增加。
以下是抓包分析的关键步骤和示例:
expect: 100-continue
头的请求。expect
头的请求和后续发送请求主体的时间戳,确认延迟发生的具体位置。100 continue
响应的过程中出现了明显延迟。frame 1: 102 bytes on wire (816 bits), 102 bytes captured (816 bits) on interface eth0, id 0
arrival time: jan 1, 2024 15:45:12.123456789 utc
[time shift for this packet: 0.000000000 seconds]
epoch time: 1672598712.123456789 seconds
[time delta from previous captured frame: 0.000000000 seconds]
[time delta from previous displayed frame: 0.000000000 seconds]
[time since reference or first frame: 0.000000000 seconds]
frame number: 1
frame length: 102 bytes (816 bits)
capture length: 102 bytes (816 bits)
[frame is marked: false]
[frame is ignored: false]
[protocols in frame: eth:ethertype:ip:tcp:http]
ethernet ii, src: vmware_00:00:00 (00:50:56:c0:00:08), dst: vmware_00:00:01 (00:50:56:c0:00:01)
internet protocol version 4, src: 10.0.0.2, dst: 10.0.0.3
transmission control protocol, src port: 49152, dst port: 80, seq: 1, ack: 1, len: 40
hypertext transfer protocol
get / http/1.1\r\n
host: www.example.com\r\n
user-agent: curl/7.68.0\r\n
accept: */*\r\n
expect: 100-continue\r\n
\r\n
通过深入分析抓包数据,我们注意到客户端在发送请求头后,等待了较长时间才继续发送请求主体。进一步检查http头部字段,我们发现请求头中包含了expect: 100-continue
。这种配置要求服务器在收到请求头后,先返回一个100 continue
响应,然后客户端才发送请求主体。如果服务器响应不及时,客户端会等待一段时间,从而导致整体耗时增加。
为了解决这一问题,我们决定通过显式设置空的expect
头,绕过100-continue
机制,让客户端在发送请求时直接发送请求主体。具体实现如下:
std::list<std::string> lstheader;
xx_api::prom* prom = xx_api::prom::getinstance();
lstheader.push_back("content-type: application/xml;charset=utf-8");
lstheader.push_back("msgtp:" + msgtp);
lstheader.push_back("oriissrid:" + kpyeeacctissrid);
lstheader.push_back("expect:");
在实施这一改动后,我们再次进行了性能测试。监控视图显示,http请求的平均耗时显著下降,之前的几百毫秒延迟不复存在。经过多次测试和实际运行,确认这种改动有效解决了因expect: 100-continue
头导致的延迟问题。
无论是短连接还是长连接,通过去掉expect: 100-continue
头可以避免等待服务器的100 continue
响应,从而减少请求的整体耗时,提升性能。
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论