ゴールド含有量の高いダボ面接の質問 5 選!

リリース: 2023-08-17 16:04:16
転載
1082 人が閲覧しました

今日は、Dubbo IO インタラクションに関する記事をお届けします。

この記事は同僚が書いたものです。つまらない知識を面白い言葉を使ってまとめています。わかりやすくてとても面白いので、著者の記事を見つけるのが待ちきれません


いくつかの興味深い質問

Dubbo は、複雑なスレッド モデルを備えた優れた RPC フレームワークです。この記事は私の浅い知識に基づいてDubboのIOプロセス全体を分析してみようというところから始まります。始める前に、まず次の質問を見てみましょう:

  • ビジネス メソッドの実行後、データ パケットは送信されますか?
  • スレッド モデルにおける netty3 と netty4 の違いは何ですか?
  • データ パケットがオペレーティング システムのソケット バッファに到着すると何が起こったのでしょうか?
  • プロバイダーによって生成されるログにはほとんど時間がかかりませんが、コンシューマー側はタイムアウトになります。問題をトラブルシューティングするにはどうすればよいですか?
  • データ パケットは物理層のパイプを介して直接送信できますか?
  • コンシューマ ビジネス スレッドが待機中です。条件付きです。いつ起動されますか?
  • ……

次に、作成者は Dubbo2.5.3 をコンシューマとして使用し、2.7.3 をプロバイダとして使用して、インタラクション全体を説明します。プロセス. 著者のウェブサイト データ パケットの観点から、一人称で語られます。シートベルトを締めて、行きましょう。

#興味深い旅行

1. Dubbo2.5.3 消費者側がリクエストを開始します

私は Dubbo2.5.3 Consumer という小さな町で生まれたデータパケットです。私の使命は情報を届けることであり、旅行も好きです。

ある日、私は派遣されることになり、Dubbo 2.7.3 Provider というところに行くと言われました。

この日、ビジネス スレッドはメソッド呼び出しを開始しました。FailoverClusterInvoker#doInvoke でプロバイダーを選択し、さまざまなコンシューマー フィルターを通過し、次に Netty3 パイプラインを通過し、最後に NioWorker を通過しました。 #scheduleWriteIfNecessary メソッド、NioWorkerのwriteTaskQueueキューに来ました。

メインスレッドを見返してみると、DefaultFuture の Condition を待っていることが分かりましたが、何を待っているのか、どれくらい待たなければならないのかわかりませんでした。

writeTaskQueue キューにしばらく入れてみると、netty3 IO ワーカー スレッドが run メソッドを無限に実行していることがわかりました。誰もがこれを無限ループと呼んでいました。

結局、私は幸運でした。NioWorker#processWriteTaskQueue が私を選んでくれました。私はオペレーティング システムのソケット バッファーに書き込まれました。バッファー内で待機しました。とにかく、時間は十分にありました。今日のことを振り返ってみましょう。旅行中、メイン スレッドと netty3 IO ワーカー スレッドと呼ばれる 2 つのツアー グループを利用しました。まあ、どちらのツアー グループのサービスも良く、非常に効率的でした。

今日見たものをただ記録して絵に描いただけですが、もちろん重要でない部分は無視してます。

ゴールド含有量の高いダボ面接の質問 5 選!

2. オペレーティング システムがデータ パケットを送信します

私はオペレーティング システムのソケット バッファーにいますそして魔法のようなものをたくさん渡しました。

  1. #トランスポート層と呼ばれる場所に、ターゲット ポート番号とソース ポート番号を追加しました

  2. ネットワーク層と呼ばれる場所で、ターゲットIPとソースIPを追加し、同時にターゲットIPとマスクの間のAND演算を実行して「ネクストホップ」IP

    を見つけます。
  3. #データリンク層と呼ばれる場所に、ARP プロトコルを介して「ネクストホップ」のターゲット MAC アドレスとソース MAC アドレスを追加しました。

最も興味深いのは、ケーブル カーの一部を撮影したことです。ケーブル カーを変更するたびに、ターゲット MAC アドレスとソース MAC アドレスを変更する必要がありました。後で、同僚にデータ パケット情報を尋ねました。このモードは「ネクスト ホップ」と呼ばれ、ホップを次々と飛び越えます。ここにはデータパッケージがたくさんあります。大きいものは 1 つのケーブルカーにあり、小さいものは 1 つのケーブルカーに詰め込まれています。恐ろしいこともあります。大きいものは複数のケーブルに分割する必要があります車 (ただし、これはデータ パッケージには関係ありません)。質問)、これは開梱と貼り付けと呼ばれます。この間、スイッチやルーターを通過しましたが、これらの場所は非常に快適に遊べました。

もちろん、渋滞、目的地のケーブルカーは満員、連れて行ってもらう暇もないので待つしかないという嫌な事もあります。

3. プロバイダ側の経験

久しぶりに目的地に到着し、「ゼロコピー」というバスに乗りました。 " スピードボートはすぐに netty4 に到着しました。netty4 は実に素晴らしかったです。NioEventLoop#processSelectedKeys を通過し、パイプライン内のさまざまな受信ハンドラーを通過した後、AllChannelHandler のスレッド プールに到達しました。もちろん、私はたくさんのスレッド プールを持っています。選択肢はありますが、宛先をランダムに選択すると、宛先の「ビジネス メソッド」に到達する前に、デコードと一連のフィルターが実行されます。NettyCodecAdapter#InternalDecoder デコーダーは非常に強力で、解凍を処理できます。そしてくっついてます。

ゴールド含有量の高いダボ面接の質問 5 選!

AllChannelHandler のスレッドプールにしばらく滞在するので、その過程を記録するために絵も描きました。

ゴールド含有量の高いダボ面接の質問 5 選!

それ以来、私の旅は終わり、新しい物語は新しいデータパッケージによって続きます。

4. 新しいデータ パケットがプロバイダー側​​で生成されました

私は、Dubbo2 という小さなプロバイダーで生まれたデータ パケットです。 7.3タウン、私の使命は運命の糸を呼び覚ますことです 次に、Dubbo2.5.3 Consumerという場所への旅を始めます。

プロバイダー ビジネス メソッドの実行後

  • ビジネス スレッドによって渡されましたio.netty.channel.AbstractChannelHandlerContext#writeAndFlush
  • #その後、
    io.netty を通過しました.util .concurrent.SingleThreadEventExecutor#execute addTask を実行します
  • タスクをキューに入れます
    io.netty.util.concurrent.SingleThreadEventExecutor#taskQueue
  • io.netty.channel.AbstractChannelHandlerContext$WriteTask に従って、NioEventLoop が開始するのを待ち、待機中に実行した手順を記録しました。
ゴールド含有量の高いダボ面接の質問 5 選!
ここで、NioEventLoop が無限ループであり、常にタスク キューからタスクをフェッチし、タスクを実行していることがわかります。

AbstractChannelHandlerContext.WriteAndFlushTask ## #と、ソケットのバッファエリアで飽きずに待っていてくださいと指示され、完璧を追求する頑固な職人気質の持ち主であることが分かった気がしました。

io.netty.channel.AbstractChannel.AbstractUnsafe#write

の後、オペレーティング システムのソケット バッファに到達します。オペレーティング システム レベルでも、ほとんどのデータ パケットと同様に、目的地に到達するにはケーブル カーが必要です。 <h4 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;padding: 0px;font-weight: bold;color: black;font-size: 18px;"> <span style="display: none;"></span>5. dubbo 2.5.3 Consumer 側に到着<span style="display: none;"></span> </h4> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin: 0;line-height: 26px;color: black;font-size: 14px;">dubbo 2.5.3 Consumer 側に到着、オペレーティング システムでしばらく待ちましたシステム ソケット バッファー。また、「ゼロ コピー」スピードボートに乗り、実際の目的地ダボ 2.5.3 コンシューマーに到着しました。ここで、<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: #ff6441;">NioWorker#run が無限ループであることがわかり、NioWorker を実行しました。 #processSelectedKeys NioWorker#read メソッドで読み出すと、ビジネス スレッド プールである AllChannelHandler のスレッド プールに到達しました。

タスクがスケジュールされるのを待って、しばらくここで待っていました。com.alibaba.dubbo.remoting.exchange.support.DefaultFuture#doReceived が実行され、 Condition のシグナルが同時に実行されました。遠くに閉ざされた糸が目覚めるのが見えた、私が来たことで眠っていた糸が目覚めたのだと理解したようで、これが私の人生の意味だと思う。

この時点で、私の使命は完了し、この旅は終わりました。

netty3 と netty4 のスレッド モデルの概要

netty3 と netty4 のスレッド モデルを自己記述に基づいてまとめます。 2 つのデータ パケット。

1. Netty3 の書き込みプロセス

ゴールド含有量の高いダボ面接の質問 5 選!

2. Netty4 の読み取りと書き込み処理

ゴールド含有量の高いダボ面接の質問 5 選!

説明: ここには netty3 の読み込み処理はありません netty3 の読み込み処理は netty4 と同じでパイプラインが実行されますIO スレッドによって。

要約: netty3 と netty4 のスレッド モデルの違いは、書き込みプロセスにあります。netty3 では、パイプラインはビジネス スレッドによって実行されますが、netty4 では、読み取りまたは書き込みに関係なく、パイプラインはビジネス スレッドによって実行されます。 IOスレッドによって実行されます。

netty4 の ChannelPipeline のハンドラー チェーンは、I/O スレッドによって均一にシリアルにスケジュールされます。読み取り操作か書き込み操作かに関係なく、netty3 の書き込み操作はビジネス スレッドによって処理されます。 netty4ではスレッド間のコンテキスト切り替えによる消費時間を削減できますが、netty3ではビジネススレッドがハンドラチェーンを並行して実行できるようになります。 netty4 の効率低下につながる時間のかかるハンドラー操作がある場合は、これらの時間のかかる操作をハンドラーで処理するのではなく、最初にビジネス スレッドで実行することを検討できます。業務スレッドを並行して実行できるため、効率も向上します。

いくつかの困難な問題のトラブルシューティング

プロバイダーによって要求された didi.log が通常の形式で記録される場合など、いくつかの典型的な困難な問題に遭遇しました。コンシューマー側がタイムアウトしました。現時点では、次のトラブルシューティングの指示があります。didi.log のフィルターは実際には非常に内部レベルにあり、多くの場合、ビジネス メソッドの実際の実行を反映できません。

  1. #プロバイダー ビジネス ディレクションの実行に加えて、シリアル化にも時間がかかる場合があるため、arthas を使用して最も外側のメソッド org.apache.dubbo.remoting を監視できます。 Transport.DecodeHandler #received、ビジネス メソッドの長時間消費の問題を解決します。

  2. #プロバイダーでのデータ パケットの書き込みに時間がかかるかどうか、IO を監視します。 .netty.channel.AbstractChannelHandlerContext#invokeWrite メソッド

  3. Recv-Q、Send-Q など、netstat を通じて現在の TCP ソケットの一部の情報を確認することもできます。 、Recv-Q は受信バッファに到達しましたが、アプリケーション コードによってまだ読み取られていないデータです。 Send-Q は送信バッファに到達しましたが、相手はまだ Ack データを返していません。これら 2 種類のデータは通常は蓄積されませんが、蓄積されると問題が発生する可能性があります。

ゴールド含有量の高いダボ面接の質問 5 選!
  1. #Consumer NioWorker#processSelectedKeys (dubbo2.5.3) メソッドに時間がかかるかどうかを確認する。

  2. # 最終的にリンク全体の詳細を確認するまでは...問題は確実に解決できます。

終了対話プロセス全体を通じて、作成者はスレッド スタック呼び出しの詳細とソースの一部を省略しています。シリアル化と逆シリアル化、Dubbo が完全なデータ パケットを読み取る方法、ビジネス メソッドが実行される前にフィルターがどのようにソートおよび分散されるか、Netty の Reactor モードがどのように実装されるかなどのコードの詳細。とても興味深い質問ですね...

以上がゴールド含有量の高いダボ面接の質問 5 選!の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:Java后端技术全栈
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート