私は仮説を持っています:時々TCP接続は私のサーバーよりも早く到着しますaccept()
。キューがあふれるのを待つと問題が発生します。
このようなことが起こるかどうかを確認するには?
承認キューの長さまたはオーバーフローの数を監視できますか?カウンターが露出していますか?
答え1
キューがオーバーフローしていることを確認するには、netstat または nstat を使用します。
[centos ~]$ nstat -az | grep -i listen
TcpExtListenOverflows 3518352 0.0
TcpExtListenDrops 3518388 0.0
TcpExtTCPFastOpenListenOverflow 0 0.0
[centos ~]$ netstat -s | grep -i LISTEN
3518352 times the listen queue of a socket overflowed
3518388 SYNs to LISTEN sockets dropped
引用: https://perfchron.com/2015/12/26/investigating-linux-network-issues-with-netstat-and-nstat/
キューサイズを監視するには、ssコマンドを使用してSYN-RECVソケットを見つけます。
$ ss -n state syn-recv sport = :80 | wc -l
119
引用: https://blog.cloudflare.com/syn-packet-handling-in-the-wild/
答え2
システムマイニングこれらの情報のいくつかは、各システムコールの終わりにパラメータとしてaccept
提供されますqueuelen
。また、キューの長さを で表示しますqueuemax
。
7598971 21:05:30.322229280 1 gunicorn (6451) < accept fd=13(<4t>127.0.0.1:45882->127.0.0.1:8003) tuple=127.0.0.1:45882->127.0.0.1:8003 queuepct=0 queuelen=0 queuemax=10
私が知る限り、キューがオーバーフローする時期と回数を正確に知ることができるメカニズムは提供しません。これを定期的な監視や同様の監視と統合するのは面倒ですcollectd
。
答え3
sysctl -a
あなたが探しているのは、次のコマンド出力項目です。
net.ipv4.tcp_max_syn_backlog = 4096
上記の例では、SYNステータス接続のバックログは最大4096です。サーバーのRAMの量によっては、この量を増やすことができます。私の考えでは、32Kバックログは負荷の高いWebサーバーを調整するのに良いスタートだと思います。
また、以下が 1 に設定されていないことを確認してください。
net.ipv4.tcp_abort_on_overflow = 0
それ以外の場合、バックログがオーバーフローすると、パケットは確実に失われます。
sysctl -a | grep backlog
またはを使用して値を簡単に確認できますsysctl -a | grep overflow
。
また、以下に「削除済み」タグを見つけることができます。
ifconfig -a
コマンドの出力です。これは、他のデータやエラーなどと一緒にインターフェイスごとに破棄されたパケットの数を示します。
ドロップされたパケットを記録するには、RHEL 7の[有料]文書があります。https://access.redhat.com/solutions/1191593
さらなる研究のために、以下を読むことができます。http://veithen.io/2014/01/01/how-tcp-backlog-works-in-linux.html
Stevenの著書「TCP/IP Illustrated」によると、次のようになっています。
キュー制限は、[...]不完全な接続のキューのエントリ数[...]と[...]完了した接続のキューのエントリ数[...]に適用されます。 」
また、次のように指定します。
完了した接続キューはほぼ常に空です。なぜなら、このキューにエントリを入れると、サーバーから受け入れられた呼び出しが返され、サーバーはキューから完了した接続を取得するからです。
したがって、受け入れキューが完全に空のように見える可能性があるため、Total Aggregate キューに配置された接続をより早く受け入れるように Web サーバーを調整する必要があります。