机器 A 向机器 B 建立 TCP 连接,当建立了 20 万的连接后,想建立新的连接就很慢。
此时在机器 A 上用 tcpdump 抓包可以看到:有的连接可以正常三次握手,有的连接需要发多个 syn 包,有的连续发 6 次 syn 包无响应后应用层就报错了。
在机器 B 上用 ebpf 来捕获 kfree_skb 的调用,可以发现内核的确是丢包了,但是如何知道为什么会丢包呢?不知道谁能解答。此时内核日志无异常,cpu 和内存也很充足。我是用的 bpftrace 定位的,bpftrace 的执行脚本如下:
kprobe:kfree_skb
{
$skb = (struct sk_buff*) arg0;
$ip_header = ((struct iphdr *) ($skb->head + $skb->network_header));
// 这里只捕获 daddr 是 192.168.2.120 的包
if ($ip_header->daddr == 0x7802a8c0)
{
$tcp_header= ((struct tcphdr *) ($skb->head + $skb->network_header + ($ip_header->ihl << 2)));
$sport = $tcp_header->source;
$dport = $tcp_header->dest;
$dport = ($dport >> 8) | (($dport << 8) & 0xff00);
$sport = ($sport >> 8) | (($sport << 8) & 0xff00);
// 这里只捕获 dport 是 8100 的包
if ($dport == 8100) {
time("%H:%M:%S ");
printf("%s:%d > %s:%d\n", ntop($ip_header->saddr), $sport, ntop($ip_header->daddr), $dport);
}
}
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.