私は仮説を立てます:時々TCP接続が私のサーバーがそれらよりも速く到達するaccept()
です。キューがオーバーフローするまでキューに入れられ、問題が発生します。
これが起こっていることをどのように確認できますか?
受け入れキューの長さまたはオーバーフローの数を監視できますか?どこかに露出しているカウンターはありますか?
Sysdig は、accept
syscallの最後に、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
または同様のものによる定期的な監視と統合するのは面倒です。
キューがオーバーフローしているかどうかを確認するには、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/
あなたが探しているのは、sysctl -aコマンドの出力のエントリです:::
net.ipv4.tcp_max_sync_backlog = 4096
上記の例の場合、SYN状態の接続のバックログは最大4096です。RAMがサーバーにどれだけあるかに基づいて、これを増やすことができます。32Kバックログは、チューニングの良いスタートだと思います負荷の高いWebサーバーの。
また、以下が1に設定されていないことを確認してください。
net.ipv4.tcp_abort_on_overflow = 0
それ以外の場合、バックログのオーバーフローがある場合は、確実にパケットをドロップします。
簡単に確認できます
「sysctl -a | egrepバックログ」
「sysctl -a | egrepオーバーフロー」
さらに、「ドロップ」ラベルが
「ifconfig -a」
コマンドの出力。これは、他のデータやエラーなどとともに、各インターフェイスでドロップされたパケット数を示しています。
ドロップされたパケットのロギングについては、RHEL 7に有料の記事があります::
https://access.redhat.com/solutions/119159
さらなる研究のためにあなたは読むかもしれません:
http://veithen.io/2014/01/01/how-tcp-backlog-works-in-linux.html
Steven's Book Illustrated TCP/IPによると、次のように記載されています。
「キュー制限は、[…]不完全な接続キューのエントリ数[…]と[…]完了した接続キューのエントリ数[…]の合計に適用されます。 "
したがって、次のようにも述べられています。
「完了した接続キューはほとんど常に空です。このキューにエントリが置かれると、サーバーは受け入れを求める呼び出しを返し、サーバーは完了した接続をキューから取り出します。」
したがって、受け入れキューは完全に空のように見える可能性があり、(この場合は)Web Apacheサーバーを調整して、「総計」キューに配置された接続をより速く受け入れる必要があります。