「SYN から LISTEN へのソケットがドロップされる」原因は何ですか?

「SYN から LISTEN へのソケットがドロップされる」原因は何ですか?

非常に忙しいプロキシ サーバーでは、多数の「LISTEN ソケットへの SYN がドロップされました」。

原因の 1 つは、バックログ サイズが小さすぎる可能性があることを知りました。ただし、その場合、「ソケットの listen キューがオーバーフローした回数」の値は等しくなるはずです (実際は等しくありません)。

では、この動作の原因は何でしょうか? NIC が壊れているのでしょうか?

プロキシは 5 つありますが、そのうち 2 つでは 2 つの数値が等しくないため、そこでこの問題が発生しているようです。

以下は netstat からの出力です。

$ netstat -s | grep -i list
238627 times the listen queue of a socket overflowed
8610307 SYNs to LISTEN sockets dropped

サーバーには IPv4 と IPv6 のトラフィックがあるので、それが役立つかもしれませんか?

答え1

これらのカウンタは最終的にはカーネルから取得され、カウンタLINUX_MIB_LISTENOVERFLOWSLINUX_MIB_LISTENDROPSカウンタにマップされます。net/ipv4/tcp_ipv4.c(tcp_v4_syn_recv_sock)行番号 1392 付近で、LINUX_MIB_LISTENOVERFLOWSが増分されるとLINUX_MIB_LISTENDROPSも増分されますが、後者のみが増分される終了条件があるため、一致しないのはバグではありません。

同じファイル内に次のコードがあります:

1291 int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1292 {
1293         /* Never answer to SYNs send to broadcast or multicast */
1294         if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
1295                 goto drop;
1296 
1297         return tcp_conn_request(&tcp_request_sock_ops,
1298                                 &tcp_request_sock_ipv4_ops, sk, skb);
1299 
1300 drop:
1301         NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
1302         return 0;
1303 }

したがって、少なくとも 1 つの原因はブロードキャスト アドレスまたはマルチキャスト アドレスへの SYN であることがわかります。

答え2

通常、wmem と rmem のデフォルトは 212992 バイトです。 ビジー状態のサーバーでは明らかに不十分です。 8MB に増やすと、問題は解消しました。

sysctl -w net.core.wmem_default=8388608
sysctl -w net.core.rmem_default=8388608

関連情報