这个 HTTP header 导致的超时,有人遇见过吗?

2023-08-09 07:43:27 +08:00
 xuelang

在实际业务中遇到了一个很奇怪的问题,服务 A 通过 HTTP 请求访问 Go 语言的服务 B ,少部分请求会超时。进一步分析发现,如果一个请求超时,其重试也一定会超时,说明针对特定请求内容,超时是必然发生的问题。通过检查服务 B 的处理日志发现,对于超时的请求,其业务逻辑处理的耗时正常。

一开始通过排除法来分析,逐步替换怀疑有问题的模块,结果并没有定位到问题。后来通过抓包,分析正常包与超时包的区别,合理猜测有问题的部分并进行验证,最终定位到原来是 Expect: 100-continue 这个请求 HTTP header 导致了这里的超时。整个排查和修复过程,踩了不少坑,记录下来可以给大家参考。

完整内容在: 由 HTTP Header 引起的请求超时问题排查

HTTP 协议中当客户端要发送一个包含大量数据的请求时(通常是 POST 或 PUT 请求),如果服务器无法处理这个请求(例如因为请求的数据格式不正确或者没有权限),那么客户端会浪费大量的资源来发送这些数据。为了解决这个问题,HTTP/1.1 引入了 Expect: 100-continue 头部,允许客户端在发送请求体前询问服务器是否愿意接收请求。如果服务器不能处理请求,客户端就可以不发送大量数据,从而节省资源。

这里具体的实现原理是把一个完整的 HTTP 请求分成两个阶段来发送。第一个阶段只发送 HTTP 请求的头部,第二个阶段在收到服务器确认后才发送 HTTP 请求的主体。从 HTTP 的角度看,仍然是一个单一的 HTTP 请求,只是改变了请求的发送方式。

这里一般靠网络库和底层的 TCP 协议来实现,当使用了”Expect: 100-continue”头部,网络库(比如 libcurl)会先只发送 Expect 部分的 TCP 数据,然后等待服务器的 100 Continue 响应。收到 TCP 回复后,网络库会接着发送请求主体的 TCP 数据包。如果服务器没有返回 100 Continue 响应,网络库可能会选择等待一段时间,然后发送请求主体,或者关闭连接。

1740 次点击
所在节点    程序员
17 条回复
lasuar
2023-08-09 08:50:04 +08:00
课上了,该说说为何服务器没有即时响应 100 Continue ?这到底属于服务端接口问题。
crystom
2023-08-09 09:06:46 +08:00
这个过时了,客户端不建议添加
zhangkunkyle
2023-08-09 09:07:30 +08:00
学到了
dode
2023-08-09 09:08:10 +08:00
后端把这个请求头逻辑写死处理,
runliuv
2023-08-09 09:24:55 +08:00
Expect: 100-continue , 一般设置为 false.
flycat1626
2023-08-09 09:26:59 +08:00
内容都写到这份上了,还非要导流自己的 blog 吗?真想交流的话,格局还是不够大啊。
lsk569937453
2023-08-09 09:31:54 +08:00
看样子不用这个 c++库的一般不会碰到。
zzzkkk
2023-08-09 09:34:05 +08:00
所以你的 A 服务用来什么 http client
不要发 expect 100-continue 不就好了
vfs
2023-08-09 09:34:33 +08:00
这娃所有的文章看起来都是给博客导流的。。。
xuelang
2023-08-09 09:39:19 +08:00
@lasuar 对,是服务层问题,后面会继续看下服务层这里 bug 在哪里
xuelang
2023-08-09 09:39:42 +08:00
@crystom http2 就没有了,不过 1.1 里 libcurl 还是会自动加
xuelang
2023-08-09 09:40:21 +08:00
导流有啥问题吗?
xuelang
2023-08-09 09:40:49 +08:00
@lsk569937453 嗯,试了 go 的库,没有自动加这个 header
xuelang
2023-08-09 09:41:04 +08:00
@zzzkkk 最后就是这样修复的
xuelang
2023-08-09 09:42:47 +08:00
@vfs 内容主要在博客更新,这里只是分享出来而已,没必要全部重新粘贴一遍。

理解成导流没问题,不过只要不是导的垃圾流,就没啥问题吧。

关键还是看文章质量,对你有用你就看。
xuhai951753
2023-08-09 10:27:42 +08:00
我在想这种情况下是不是超时是正确的,因为服务器没处理,不然可能会过载
当然服务器因为 bug 没处理那是另外一回事
xuelang
2023-08-09 10:42:50 +08:00
@xuhai951753 这种服务 mesh 层没处理好 http 的转发,和过载没关系的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/963579

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX