【发布时间】:2020-05-12 03:13:20
【问题描述】:
我们在负载均衡器后面运行一个用 Go 编写的 HTTP 服务器。在随机数量的请求(每几亿次)之后,一个请求以某种方式分成两个数据包,第二个数据包缺少第一个字节。
我们分析了我们的服务器库 fasthttp 和 Go 的代码,但没有发现任何可以解释这种行为的东西。
接下来我们用 tcpdump 捕获了很多这样的请求,它们没有被拆分 - 整个请求都在一个 TCP 数据包中,它们看起来是正确的。
Go 服务器仍然认为有两个数据包,并且 strace 确认套接字正在被读取两次:
2289 23:09:37.239558 read(212, "GET /json HTTP/1.1\r\nContent-Type: application/x-stream\r\nAccept: application/x-stream\r\nAccept-Encoding: gzip\r\nUser-Agent: Java/Android\r\nConnection: Keep-Alive\r\nKeep-Alive: 5000\r\nHttp-version: HTTP/1.1\r\nHost: <snipsnip>\r\nX-TCPI: 91", 4096) = 229
32289 23:09:37.239620 read(212, "217.26.11 \r\n\r\n", 3867) = 16
所以我们认为它要么是负载均衡器,在这种情况下,tcpdump 会以某种方式修改数据包以使其看起来正确,要么是内核。
接下来我们应该看哪里?
【问题讨论】:
标签: linux networking tcp kernel