オンラインの問題の場所-ネットワークのボトルネック

パケット損失とエラーパケットの状況を特定する

watch more /proc/net/devネットワークのボトルネックを確認するために、パケット損失とエラーパケットの状況を特定するために使用されます。ドロップ(パケットがドロップされる)とネットワークパケット送信の合計量に注目し、ネットワークの上限を超えないようにします。

[root@localhost ~]# watch -n 2 more /proc/net/dev
Every 2.0s: more /proc/net/dev                                                                                                                                                   Fri May  1 17:16:55 2020

Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo:   10025     130    0    0    0     0          0         0    10025     130    0    0    0     0       0          0
 ens33: 759098071  569661    0    0    0     0          0         0 19335572  225551    0    0    0     0       0          0
  • 左端はインターフェースの名前を表し、Receiveは受信パケットを表し、Transmitは送信パケットを表します。

  • bytes:送受信されたバイト数を示します。

  • packets:送受信された正しいパケット量を示します。

  • errs:誤って送受信されたパケットの量を示します。

  • drop:送受信された廃棄パケットの量を示します。

ルートを通過した住所を表示する

traceroute ipルートによって渡されたアドレスを表示できます。これは、次のように、各ルーティングセクションでネットワークの消費時間をカウントするためによく使用されます。

[root@localhost ~]# traceroute 14.215.177.38
traceroute to 14.215.177.38 (14.215.177.38), 30 hops max, 60 byte packets
 1  CD-HZTK5H2.mshome.net (192.168.137.1)  0.126 ms * *
 2  * * *
 3  10.250.112.3 (10.250.112.3)  12.587 ms  12.408 ms  12.317 ms
 4  172.16.227.230 (172.16.227.230)  2.152 ms  2.040 ms  1.956 ms
 5  172.16.227.202 (172.16.227.202)  11.884 ms  11.746 ms  12.692 ms
 6  172.16.227.65 (172.16.227.65)  2.665 ms  3.143 ms  2.923 ms
 7  171.223.206.217 (171.223.206.217)  2.834 ms  2.752 ms  2.654 ms
 8  182.150.18.205 (182.150.18.205)  5.145 ms  5.815 ms  5.542 ms
 9  110.188.6.33 (110.188.6.33)  3.514 ms 171.208.199.185 (171.208.199.185)  3.431 ms 171.208.199.181 (171.208.199.181)  10.768 ms
10  202.97.29.17 (202.97.29.17)  29.574 ms 202.97.30.146 (202.97.30.146)  32.619 ms *
11  113.96.5.126 (113.96.5.126)  36.062 ms 113.96.5.70 (113.96.5.70)  35.940 ms 113.96.4.42 (113.96.4.42)  45.859 ms
12  90.96.135.219.broad.fs.gd.dynamic.163data.com.cn (219.135.96.90)  35.680 ms  35.468 ms  35.304 ms
13  14.215.32.102 (14.215.32.102)  35.135 ms 14.215.32.110 (14.215.32.110)  35.613 ms 14.29.117.242 (14.29.117.242)  54.712 ms
14  * 14.215.32.134 (14.215.32.134)  49.518 ms 14.215.32.122 (14.215.32.122)  47.652 ms
15  * * *
...

ネットワークエラーを表示する

netstat -iネットワークエラーを表示できます。

[root@localhost ~]# netstat -i
Kernel Interface table
Iface             MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
ens33            1500   570291      0      0 0        225897      0      0      0 BMRU
lo              65536      130      0      0 0           130      0      0      0 LRU
  • Iface:ネットワークインターフェース名;

  • MTU:データフレームの最大長を制限する最大伝送ユニット。さまざまなネットワークタイプには、次のような上限があります。イーサネットMTUは1500です。

  • RX-OK:受信時の正しい数のデータパケット。

  • RX-ERR:受信時にエラーが発生したパケットの数。

  • RX-DRP:受信時に破棄されたデータパケットの数。

  • RX-OVR:受信時、速度超過により失われたデータパケットの数(データ送信では、受信デバイスが送信レートで送信されたデータを受信できないため、データが失われます)。

  • TX-OK:送信時の正しいパケット数。

  • TX-ERR:送信時にエラーが発生したデータパケットの数。

  • TX-DRP:送信時に破棄されたデータパケットの数。

  • TX-OVR:送信時の速度超過により失われたデータパケットの数。

  • Flg:マーク、Bがブロードキャストアドレスを設定しました。Lこのインターフェイスはループバックデバイスです。Mはすべてのパケットを受信します(カオスモード)。N追跡を避けます。○このインターフェースで、ARPを無効にします。Pこれはポイントツーポイントリンクです。Rインターフェイスが実行されています。Uインターフェイスは「アクティブ」状態です。

パケット再送率

cat /proc/net/snmpこれは、240秒以内のネットワークパケット量、トラフィック、エラーパケット、およびパケット損失を表示および分析するために使用されます。よるRetransSegsと、OutSegs計算された再送率tcpetr=RetransSegs/OutSegs

[root@localhost ~]# cat /proc/net/snmp
Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates
Ip: 1 64 241708 0 0 0 0 0 238724 225517 15 0 0 0 0 0 0 0 0
Icmp: InMsgs InErrors InCsumErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps
Icmp: 149 0 0 50 99 0 0 0 0 0 0 0 0 0 147 0 147 0 0 0 0 0 0 0 0 0 0
IcmpMsg: InType3 InType11 OutType3
IcmpMsg: 50 99 147
Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts InCsumErrors
Tcp: 1 200 120000 -1 376 6 0 0 4 236711 223186 292 0 4 0
Udp: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors
Udp: 1405 438 0 1896 0 0 0
UdpLite: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors
UdpLite: 0 0 0 0 0 0 0

再送信率= 292 /223186≈0.13%

  • 1秒あたりの新しいTCP接続の平均数:/ proc / net / snmpファイルを介して過去240秒間のPassiveOpensの増加を取得し、240で割って1秒あたりの平均増加を取得します。

  • マシンのTCP接続の数:/ proc / net / snmpファイルのCurrEstabを介してTCP接続の数を取得します。

  • 1秒あたりの平均UDP受信データグラム:/ proc / net / snmpファイルを介して過去240秒間のInDatagramの増分を取得し、240で除算して1秒あたりの平均UDP受信データグラムを取得します。

  • 1秒あたりに送信される平均UDPデータグラム:/ proc / net / snmpファイルを介して過去240秒間のOutDatagramの増分を取得し、240で除算して1秒あたりの平均UDPデータグラムを取得します。

タイムアウト

タイムアウトエラーのほとんどはアプリケーションレベルで発生するため、これは概念の理解に焦点を当てています。タイムアウトは、接続タイムアウトと読み取り/書き込みタイムアウトに大別できます。接続プールを使用する一部のクライアントフレームワークには、接続取得タイムアウトとアイドル接続クリーンアップタイムアウトもあります。

  • 読み取りと書き込みのタイムアウト。readTimeout / writeTimeout、一部のフレームワークはso_timeoutまたはsocketTimeoutと呼ばれ、どちらもデータの読み取りと書き込みのタイムアウトを参照します。ここでのタイムアウトのほとんどは論理タイムアウトを参照していることに注意してください。soaのタイムアウトは、読み取りタイムアウトも指します。読み取りと書き込みのタイムアウトは通常、クライアントに対してのみ設定されます。

  • 接続がタイムアウトしました。connectionTimeout、クライアントは通常、サーバーとの接続を確立するための最大時間を参照します。サーバー側のconnectionTimeoutは少し異なり、jettyはアイドル接続のクリーンアップ時間を表し、tomcatは接続が維持される最大時間を表します。

  • その他。接続取得タイムアウトconnectionAcquireTimeoutおよびアイドル接続クリーンアップタイムアウトidleConnectionTimeoutを含みます。これは主に、接続プールまたはキューを使用するクライアントまたはサーバーフレームワークに使用されます。

さまざまなタイムアウトを設定する場合、接続が正常に終了するように、クライアントのタイムアウトをサーバーのタイムアウトよりも短くしようとしていることを確認する必要があります。

実際の開発では、私たちが最も気にするのは、インターフェースの読み取りと書き込みのタイムアウトです。

適切なインターフェイスタイムアウトを設定する方法が問題です。インターフェイスのタイムアウトの設定が長すぎると、サーバーのtcp接続を占有しすぎる可能性があります。インターフェイス設定が短すぎると、インターフェイスのタイムアウトが頻繁に発生します。

サーバーインターフェイスは明らかにrtを減らしますが、クライアントはそれでもタイムアウトします。これは別の問題です。この問題は実際には非常に単純です。クライアントからサーバーへのリンクには、ネットワーク送信、キューイング、およびサービス処理が含まれます。各リンクは時間のかかる原因である可能性があります。

TCPキューオーバーフロー

TCPキューのオーバーフローは比較的低レベルのエラーであり、タイムアウトやrstなどのより表面的なエラーを引き起こす可能性があります。したがって、エラーはより隠されているので、個別に説明しましょう。

画像

上の図に示すように、2つのキューがあります。synsキュー(半接続キュー)とacceptキュー(完全接続キュー)です。スリーウェイハンドシェイク。サーバーはクライアントのsynを受信すると、メッセージをsynsキューに入れ、syn + ackでクライアントに応答します。サーバーはクライアントのackを受信します。この時点でacceptキューがいっぱいでない場合は、 synsキューから一時ストレージを取り出します。情報はacceptキューに入れられます。それ以外の場合は、tcp_abort_on_overflowで示されるように実行されます。

tcp_abort_on_overflow 0は、スリーウェイハンドシェイクの3番目のステップで受け入れキューがいっぱいになった場合、サーバーがクライアントから送信されたackを破棄することを意味します。tcp_abort_on_overflow 1は、3番目のステップで完全な接続キューがいっぱいになると、サーバーが最初のパケットをクライアントに送信することを意味します。これは、ハンドシェイクプロセスとこの接続が廃止されたことを示します。つまり、ログ内のピア。

では、実際の開発では、どのようにしてtcpキューのオーバーフローをすばやく見つけることができますか?

  • netstatコマンド、netstat -s | egrep "listen | LISTEN"を実行します

画像

上の図に示すように、オーバーフローは完全に接続されたキューのオーバーフローの数を表し、ドロップされたソケットは半接続されたキューのオーバーフローの数を表します。

  • ssコマンド、ss-lntを実行します

画像

上記のように、Send-Qは、3番目の列のリッスンポートで完全に接続されたキューの最大数が5であることを示し、最初の列のRecv-Qは、完全に接続されたキューが現在使用されている量です。

次に、完全に接続されたキューと半接続されたキューのサイズを設定する方法を見てみましょう。

完全に接続されたキューのサイズは、min(backlog、somaxconn)によって異なります。バックログはソケットの作成時に渡され、somaxconnはOSレベルのシステムパラメータです。半接続キューのサイズは、max(64、/ proc / sys / net / ipv4 / tcp_max_syn_backlog)によって異なります。

日常の開発では、サーブレットコンテナをサーバーとして使用することが多いため、コンテナの接続キューのサイズに注意する必要がある場合があります。TomcatのバックログはacceptCountと呼ばれ、jettyではacceptQueueSizeと呼ばれます。

RST例外

RSTパケットは接続のリセットを表し、いくつかの役に立たない接続を閉じるために使用されます。これは通常、4つの手の波とは異なる異常な閉じを表します。

実際の開発では、RSTパッケージが原因で発生するピアエラーによる接続リセット/接続リセットがよく見られます。

1.ポートが存在しません

接続を確立するためのSYN要求が、存在しないポートのように発行された場合、サーバーは、このポートがないことを検出すると、接続を中断するためにRSTメッセージを直接返します。

2. FINを積極的に交換して、接続を終了します

一般的に、通常の接続閉鎖はFINメッセージを介して達成する必要がありますが、FINの代わりにRSTメッセージを使用することもできます。これは、接続が直接終了することを意味します。実際の開発では、SO_LINGER値を制御に設定できます。これは、多くの場合、意図的なものであり、TIMED_WAITをスキップし、インタラクティブな効率を提供し、注意して使用します。

3.クライアントまたはサーバーの一方の側で例外が発生し、反対側がRSTを送信して接続を閉じるように通知します

RSTパケットを送信する上記のtcpキューオーバーフローは、実際にはこの種類に属します。これは多くの場合、何らかの理由で、一方の当事者が要求接続を通常は処理できなくなり(たとえば、プログラムがクラッシュしたり、キューがいっぱいになったり)、他方の当事者に接続を閉じるように指示します。

4.受信したTCPパケットが既知のTCP接続にありません

たとえば、一方のマシンでネットワークの不良が原因でTCPパケットが欠落している場合、もう一方のパーティは接続を閉じてから、長い時間後に欠落しているTCPパケットを受信しますが、対応するTCP接続が存在しないため、送信します。新しい接続を開くために1つの直接RSTパケット。

5.一方の当事者が他方の当事者から確認メッセージを長時間受信しておらず、一定期間後または再送信回数後にRSTメッセージを送信します。

このほとんどはネットワーク環境にも関連しています。ネットワーク環境が悪いと、RSTパケットが増える可能性があります。

RSTメッセージが多いとプログラムがエラーを報告することを前に述べました。閉じた接続での読み取り操作は接続のリセットを報告し、閉じた接続での書き込み操作はピアによる接続のリセットを報告します。通常、パイプの破損エラーも発生する場合があります。これはパイプレベルのエラーです。これは、閉じたパイプの読み取りと書き込みを意味します。RSTを受信し、接続リセットエラーを報告した後、データの読み取りと書き込みを続行するとエラーになることがよくあります。 glibcのソースコードコメントでも紹介されています。

トラブルシューティング時にRSTパケットの存在をどのように判断しますか?もちろん、tcpdumpコマンドを使用してパケットをキャプチャし、wiresharkを使用して簡単な分析を行います。tcpdump -i en0 tcp -w xxx.cap、en0は監視ネットワークカードを表します。

画像

次に、キャプチャしたパケットをwiresharkで開きます。次の図が表示される場合があります。赤い図は、RSTパケットを表しています。

画像

TIME_WAIT和CLOSE_WAIT

TIME_WAITとCLOSE_WAITの意味は誰もが知っていると思います。

オンラインの場合、コマンドnetstat -n | awk '/ ^ tcp / {++ S [$ NF]} END {for(a in S)print a、S [a]}'を直接使用して、待機時間を表示できます。そしてclose_waitの数

ssコマンドを使用すると高速になりますss-ant | awk '{++ S [$ 1]} END {for(a in S)print a、S [a]}'

1、TIME_WAIT

time_waitの存在は、失われたデータパケットが後続の接続で再利用されるためのものであり、2つ目は、2MSLの時間範囲内で通常どおり接続を閉じるためのものです。その存在により、実際にはRSTパケットの出現が大幅に減少します。

頻繁に短い接続があるシナリオでは、time_waitが多すぎる可能性が高くなります。この場合、いくつかのカーネルパラメータの調整をサーバー側で実行できます。

#再利用がオンになっていることを示します。TIME-WAITソケットを新しいTCP接続に再利用できるようにします。デフォルトは0です。これは、ソケットが閉じていることを意味します。

net.ipv4.tcp_tw_reuse = 1

#TCP接続のTIME-WAITソケットの高速リカバリがオンになっていることを示します。デフォルトは0です。これは、ソケットが閉じていることを意味します。

net.ipv4.tcp_tw_recycle = 1

もちろん、タイムスタンプが正しくないためにNAT環境でデータパケットが拒否されるという落とし穴を忘れてはなりません。別の方法は、tcp_max_tw_bucketsを変更することです。この数を超えるtime_waitはすべて強制終了されますが、これにより、待機時間のレポートも作成されます。バケットテーブルのオーバーフロー。間違っています。

2、CLOSE_WAIT

Close_waitは、多くの場合、アプリケーションによって書き込まれた問題が原因であり、ACK後にFINメッセージが再度開始されることはありません。close_waitの確率はtime_waitの確率よりもさらに高く、結果はより深刻です。多くの場合、場所がブロックされ、接続が適切に閉じられていないため、すべてのスレッドが徐々に消費されます。

このような問題を見つけるには、jstackを使用してスレッドスタックを分析し、問題のトラブルシューティングを行うのが最善です。これはほんの一例です。

開発クラスメートは、アプリケーションがオンラインになった後、ハングアップするまでCLOSE_WAITが増加したと述べました。jstackが疑わしいスタックを見つけた後、ほとんどのスレッドがcountdownlatch.awaitメソッドでスタックしました。開発クラスメートについて調べた後、彼らはマルチ-スレッドが使用されましたが、使用されませんでした。例外をキャッチします。変更後に検出された例外は、SDKのアップグレード後に頻繁に表示される、検出されなかった最も単純なクラスです。

 

おすすめ

転載: blog.csdn.net/weixin_42073629/article/details/115278858