面接での質問⑤

1. TCPとUDPの違い

UDP TCP
繋がってるのかな 接続なし、即時送信 接続指向の 3 ウェイ ハンドシェイク
信頼できますか 信頼性の低い伝送、ネットワークの変動、混雑によっても伝送が遅くなることはありません フロー制御と輻輳制御による信頼性の高い伝送
接続オブジェクトの数 1対1、1対多、多対1、多対多のインタラクティブな通信をサポート 1対1のコミュニケーションのみ
転送方法 パケット指向の順序どおりでないパケット損失が発生する可能性がある バイトストリームを重視し、信頼性の高い送信順序を確保
頭のオーバーヘッド ヘッダーのオーバーヘッドは小さく、わずか 8 バイトです 最初の部分は小さい 20 バイト、大きい 60 バイトです。
シーン リアルタイムアプリケーション(IP電話、ビデオ会議、ライブブロードキャストなど)に適しています。 ファイル転送など、信頼性の高い転送が必要なアプリケーションに適しています。

1.1 TCP/IPネットワークモデル

        コンピュータが相互に通信するには、統一されたルール (プロトコル) を指定する必要があります。

        TCP/IP は、TCP、UDP、IP、ICMP、SMTP、HTTP などのさまざまなインターネット プロトコルの総称です。

        プロトコルは、リンク層、ネットワーク層、トランスポート層、アプリケーション層の 4 つの層に分けることができます。

リンク層: IP パケットのカプセル化とカプセル化解除、ARP/RARP パケットの送受信を担当します。

ネットワーク層: ターゲット ネットワークまたはホストへのパケットのルーティングと送信を担当します。

トランスポート層: メッセージのグループ化と再構成、および TCP または UDP プロトコル形式でのメッセージのカプセル化を担当します。

アプリケーション層: ユーザーにアプリケーションを提供する責任を負います

OSI 7 層モデル TCP/IPの概念モデル 関数 TCP/IP プロトコル ファミリ
アプリケーション層 アプリケーション層 ファイル転送、電子メール、ファイルサービス、仮想端末 TFTP/HTTP/SNMP/FTP/SMTP/DNS/Telnet
プレゼンテーション層 データのフォーマット、トランスコーディング、データの暗号化 /
セッション層 他のノードとの接続を切断または確立する /
トランスポート層 トランスポート層 エンドツーエンドのインターフェースを提供します TCP/UDP
ネットワーク層 ネットワーク層 パケットのルーティング IP/ICMP/RIP/OSPF/BGP/IGMP
データリンク層 リンク層 宛先フレームの送信とエラー検出機能 SLIP/CSLIP/PPP/ARP/RARP/MTU
物理層 物理メディア上のデータをバイナリデータとして転送 ISO2110/IEEE803/IEEE802.2

         ネットワークアーキテクチャにおける通信の確立は、通信双方の同じ層で行われ、データが送信側の各層を通過する際には、対応する層のプロトコルヘッダーとプロトコルテール(プロトコルヘッダーのみ)を付加する必要があります。データリンク層はプロトコル末尾をカプセル化する必要があります)

1.2 UDP (ユーザー データグラム プロトコル)

       ネットワークでは、UDP は、TCP プロトコルと同様にデータ パケットを処理するために使用されます。これは、コネクションレスで信頼性の低いトランスポート層プロトコルです。UDP は、データ パケットのグループ化とアセンブリを提供せず、データ パケットの並べ替えもできず、データ セキュリティも保証できません (信頼性の低い : UDP)送信側で UDP ヘッダーをデータに追加してネットワーク層に渡し、受信側の UDP で IP ヘッダーを削除してアプリケーション層に渡します。

        UDP は 1 対 1、1 対多、多対 1、多対多の伝送方式 (ユニキャスト、マルチキャスト、ブロードキャスト) をサポートしており、UDP はネットワークの変動に関係なく常に一定の速度でデータを送信します。パケット損失が少ないため、リアルタイム要件に適しています ハイシーン (ライブブロードキャスト、電話会議)

        UDPヘッダのデータ量が少なく、データグラムの伝送効率が高い

1.3 TCP (伝送制御プロトコル)

        TCP プロトコルは、接続指向で信頼性の高い、バイト ストリーム ベースのトランスポート層プロトコルです。データを送信する前に、両者は接続を提案する必要があります (クライアントとサーバーはそれぞれ、相手の IP、ポート、 3 ウェイ ハンドシェイクと 4 ウェイ ハンドシェイクにより、データの完全かつ連続した送信が保証されます。

1.3.1 TCP の 3 方向ハンドシェイクと 4 方向ハンドシェイク

        スリーウェイ ハンドシェイクの本質は、最初に双方のデータの送受信能力を確認することです。A は B にメッセージを送信します。B はそれを受信した後、A の送受信能力が一致することを知り、その後、 B は確認メッセージを A に送り返します。A は、B の送受信能力が良好であり、自分自身の送受信能力も良好であることを知っています。そして、A は B にフィードバックを送信し、B は自分の送信能力が良好であることを知っています。 Aさんの受信能力は良好で、両者は正式にコミュニケーションを開始できます

最初の握手:

        クライアントはサーバーへの接続要求を開始し、クライアントはシーケンス番号 ISN (x) をランダムに生成します。クライアントからサーバーに送信されるメッセージ セグメントには SYN フラグ (SYN=1) とシーケンス番号 seq=x が含まれます。

2回目のハンドシェイク:

        サーバーはクライアントから送信されたメッセージを受信し、SYN=1 であることを確認し、それが接続要求であることを認識し、クライアントのシリアル番号 seq を保存し、サーバーのシリアル番号 (y) をランダムに生成して、メッセージを返信します。クライアントへのテキスト。SYN および ACK フラグ (SYN=1、ACK=1)、シリアル番号 seq=y、確認番号 ack=x+1 を含む

3回目の握手:

        サーバーからの応答を受信した後、クライアントは ACK=1 および ack=x+1 を確認し、サーバーがシリアル番号 x のメッセージを受信したことを知り、また SYN=1 も確認し、サーバーが同意したことを知ります。サーバーのシーケンスが保存され、クライアントは ACK フラグ (ACK=1)、ack=y+1、seq=x+1 (最初のハンドシェイク) を含むメッセージをサーバーに返信します。シリアル番号を占有します。そのため、今回は 1 を追加します。データを運ばない ACK メッセージはシリアル番号を占有しないため、後で正式に送信されるデータの順序は、サーバーがメッセージを受信した時点でも x+1 のままです。 ACK=1 および ack= y+1 であることがわかり、カスタマー サービス エンドがシリアル番号 y のメッセージを受信したことがわかります。そのため、カスタマー サービス エンド サーバーは TCP 経由で接続を確立します。

         4 つのウェーブの目的は接続を閉じることです

最初の波:

        クライアントのデータ送信が完了すると、クライアントは FIN フラグ (FIN=1)、シーケンス番号 seq=u (u=x+) を含む接続解放メッセージを送信します (送信が完了していなくても送信できます)。 1+ノードの送信データのワード)、クライアントはデータを送信できず、FIN メッセージの送信後にのみデータを受信します (FIN メッセージで運ばれるデータもシリアル番号を占有します)。

第二波:

        クライアントによって送信された FIN メッセージを受信した後、サーバーは、ACK フラグ (ACK=1)、確認番号 ack=u+1、シーケンス番号 seq=v (v=y+1) を含む確認メッセージでクライアントに応答します。 + クライアントの FIN メッセージを送信する前にサーバーが応答したデータ バイト数)、この時点では、サーバーはシャットダウン待機状態にあり、すぐには FIN メッセージをクライアントに送信せず、データが送信されるまで待機します。送信済み

第三の波:

        サーバーが最終データを送信した後、FIN および ACK フラグ (FIN=1、ACK=1)、確認番号 ack=u+1 (2 番目のウェーブと一致)、シリアル番号を含む接続解放メッセージをクライアントに送信します。 seq=w (w=v+最後に送信されたデータのバイト数)

第 4 の波:

       サーバーによって送信された FIN メッセージを受信した後、クライアントは ACK フラグ (ACK=1)、確認番号 ack=w+1、シーケンス番号 seq=u+1 を含む確認メッセージをサーバーに送信します。メッセージを確認した後、TCP 接続はすぐには解放されませんが、TCP 接続は 2MSL (最長メッセージ セグメントの存続期間の 2 倍) 後に解放され、サーバーはクライアントから送信された確認メッセージを受信すると、そのメッセージを解放します。すぐにTCP接続

2. フォワードプロキシとリバースプロキシとは何ですか

フォワードプロキシ:クライアントとターゲットサーバーの間にあるサーバー (プロキシサーバー) を指し、ターゲットサーバーからコンテンツを取得するために、クライアントはプロキシサーバーにリクエストを送信してターゲットを指定し、プロキシサーバーはコンテンツを転送します。ターゲットサーバーにリクエストを送信し、取得したコンテンツがクライアントに返されるため、ターゲットサーバーは実際のクライアントが誰であるかを知りません。

フォワード プロキシ機能:アクセス制限を突破し、アクセス速度を向上させます (通常、プロキシ サーバーは大きなハードディスク バッファを設定し、要求された応答の一部をバッファに保存します)、クライアントの実際の IP を (攻撃から) 隠します。

リバースプロキシ:クライアントが接続要求を認識しないように、クライアントの接続要求を受信し、その要求を内部ネットワーク上のサーバーに転送し、サーバーから得られた結果を接続を要求しているクライアントに返すプロキシ サーバーを指します。本当のターゲットサーバーは誰ですか

リバースプロキシ機能:サーバーの実IPの隠蔽、ロードバランシング(実サーバーの負荷に応じてクライアントリクエストを異なる実サーバーに分散)、アクセス速度の向上(リバースプロキシサーバーは静的コンテンツや短時間で使用可能)アクセス要求が多い動的コンテンツのキャッシュ サービスを提供する)、セキュリティを提供する(リバース プロキシ サーバーをアプリケーション ファイアウォールとして使用できる)、Web 攻撃の動作に基づいて Web サイトを保護する、マルウェアのトラブルシューティングを容易にする、バックエンドサーバーに統合暗号化を提供します(HTTP アクセス認証など)。

3. JVMランタイムデータ領域

プログラムカウンター:

        これは、現在のスレッドによって実行されるバイトコードの行番号インジケーターであり、メモリ空間は小さなスレッドにプライベートです。バイトコード パーサーの仕事は、このカウンターの値を変更することによって、実行する次のバイトコード命令を選択することです。分岐、ループ、ジャンプ、例外処理、スレッド回復、およびその他の関数は、完了するためにこのカウンターに依存する必要があります。

        スレッドが Java メソッドを実行する場合、カウンタは実行中の仮想マシンのバイトコード命令のアドレスを記録します。スレッドがネイティブ メソッドを実行する場合、カウンタの値は未定義になります。

        このメモリ領域は、JVM 仕様で OutOfMemoryError 条件が指定されていない唯一の領域です。

仮想マシンスタック:

        スレッドはプライベートであり、ライフサイクルはスレッドと一致しています。ローカル変数テーブル、オペランド スタック、ダイナミック リンク、メソッド出口などの情報を格納するために使用されます (ローカル変数テーブル: 基本的なデータ型と既知のオブジェクト参照を格納します)コンパイラ);

        要求されたスタックの深さが利用可能な最大深さより大きい場合は、stackOverflowError がスローされます。スタックが動的に拡張可能であっても、拡張をサポートするメモリ領域がない場合は、OutofMemoryError がスローされます。

ネイティブメソッドスタック:

        仮想マシン スタックの機能は、仮想マシン スタックの機能と一致していますが、仮想マシン スタックは Java メソッドを提供し、ローカル メソッド スタックは仮想マシンがネイティブ メソッドを呼び出すために機能する点が異なります。

ヒープ:

        Java 仮想マシンの最大のメモリ部分は、すべてのスレッドによって共有されます。主にオブジェクト インスタンスと配列を格納します。複数のスレッド プライベート割り当てバッファ TLAB を内部で分割します。物理的には不連続ですが、論理的には連続したスペースに配置できます。ヒープの場合、スペース不足のインスタンス割り当て、OutOfMemoryError

メソッド領域:

        共有メモリ領域に属し、仮想マシンによってロードされたクラス情報、定数、静的変数、ジャストインタイムでコンパイルされたコードを保存するために使用されます。

4. JVM はオブジェクトがリサイクル可能かどうかをどのように判断するか 

参照カウント方法:

        オブジェクトに参照カウンタを追加し、参照を追加するとカウントを1加算し、参照が解放されるとカウントを1減算し、カウントが0になったら再利用できるオブジェクトの問題を解決するのは困難循環参照 (オブジェクトは相互に参照します。プログラムで使用されていなくても、再利用できません)

アクセシビリティ分析:

        GC ルート (オブジェクトのグループがリサイクルできないアクティブなオブジェクトであることを示すガベージ コレクション ルート ノード) から下方向の検索を開始します。検索によって移動されるパスは参照チェーンと呼ばれます。オブジェクトに参照チェーンが接続されていない場合は、 GC ルート、これはこのオブジェクトが利用できないことを証明します

        到達可能性解析で到達不可能と判断されたオブジェクトは、初めてマークされ、一度スクリーニングされます。スクリーニング条件は、オブジェクトがファイナライズメソッドを実行する必要があるかどうかです。オブジェクトがファイナライズメソッドをオーバーライドしていない場合、またはファイナライズメソッドが呼び出された場合仮想マシンの実装は不要と考えられます

        ファイナライズ メソッドを実行する必要があると判断されると、オブジェクトは F-Queue と呼ばれるキューに入れられて実行を待機します。ファイナライズ メソッドが実行される前に、GC は 1 秒間 F-Queue 内のオブジェクトをマークします。一時オブジェクトが参照チェーン上のいずれかのオブジェクトに関連付けられている場合、一時オブジェクトは再利用されません。

5. JVM のガベージ コレクション アルゴリズムは何ですか?

マーククリア アルゴリズム:
最初に、再利用する必要があるすべてのオブジェクトをマークし、マークが完了したら、マークされたすべてのオブジェクトをリサイクルします。マークが完了したら、残っているオブジェクトを別のブロックにコピーし、使用済みのメモリ領域をクリアします。
圧縮アルゴリズム:まず、リサイクルする必要があるすべてのオブジェクトをマークし、マークされていないすべてのオブジェクトを一方の端に移動させ、その後クリーンアップします。 この端を越えた領域の
世代別コレクション アルゴリズム。各世代の特性に応じて最適な収集アルゴリズムを使用する 新世代がガベージコレクションされるたびに大量のオブジェクトが死ぬ場合はコピーアルゴリズムを使用する 生存率の高い旧世代の中型オブジェクトはマークスイープを使用するアルゴリズム

6. JVM メモリ割り当て戦略と回復戦略

  1.  オブジェクトは最初にヒープの Eden 領域に割り当てられます
  2. 大きなオブジェクトは古い世代に直接転送されます
  3. 寿命の長いオブジェクトは古い世代に直接引き継がれます

ガベージ コレクションを効率的に行うために、仮想マシンはヒープ メモリを新世代、旧世代、永続世代の 3 つの領域に分割します。

新しい世代:

        新しい世代は Eden と Survivor で構成されます (デフォルトのサイズ比は 8:1)。Eden は新世代の最大の領域であり、新しく作成されたオブジェクトを格納するために使用されます。Eden 領域がいっぱいになると、マイナー GC (新しい参照されなくなったオブジェクトをリサイクルし、生き残ったオブジェクトを Survivor スペースにコピーして、Eden をクリアします。

        Survivor スペースは通常、S0 と S1 と呼ばれる 2 つの等しいサイズの領域に分割されます。マイナー GC が発生すると、Eden の生き残ったオブジェクトはスペース S0 の 1 つにコピーされ、もう 1 つのスペース S1 はガベージ コレクションに使用されます。再び GC が発生し、Eden と S0 に残っているオブジェクトは常に交換されるように S1 領域に移動され、Survivor に移動された時点からオブジェクトの GC 年齢が蓄積され始めます。オブジェクトがデフォルトのしきい値の 15 を超えると、オブジェクトは古い時代に移動されます

旧世代:

        メジャー GC/フル GC は、古い世代に十分なスペースがない場合にトリガーされ、速度はマイナー GC より 10 倍以上遅くなります。メジャー GC は、新しい世代、古い世代、永続世代に対してガベージ コレクションを実行します (またはメタスペース)

永続的な生成: (Java8 以降はメタスペースを使用します)

        クラスのメタデータ (クラス構造情報、メソッド情報、フィールド情報、定数プールなど) を格納するために使用されます。永続世代のサイズは、通常は制限されているため、アプリケーションのクラス読み込み要件に従って割り当てる必要があります。オーバーフローしやすく、永続的にゴミが生成される リサイクルは通常、アプリケーションが停止されたときに行われます

メタスペース:

        メタスペースはヒープ メモリの一部ではなくなり、ローカル メモリ内の領域になりました。サイズは永続世代のサイズによって制限されなくなりました。ローカル メモリの制限に達するまで、プログラム要件に従って動的に拡張できます。クラスローダーは特定のクラスを参照しなくなりました。これらのクラスとそれに関連するメタデータは、次の場合にリサイクルされます。

7. クラスのライフサイクル

        解析フェーズは初期化後に開始できます (ランタイム バインディング、動的バインディング、遅延バインディング)。

ロード: JVM はクラスのバイナリ データを検索してロードします。

  • このクラスを完全修飾名で定義するバイナリ バイト ストリームを取得します (ZIP パッケージ、ネットワーク、JSP 生成、計算生成、データベース読み取り)。
  • このバイト ストリームで表される静的ストレージ構造をメソッド領域の実行時データ構造に変換します。
  • このクラスを表す java.lang.Class オブジェクトを、メソッド領域内のこのクラスのさまざまなデータへのアクセス エントリとしてメモリ内に生成します。

ロード段階が完了すると、バイナリ バイト ストリームが JVM に必要な形式でメソッド領域 (永続生成/メタスペース) に保存されます。

検証:クラス ファイルからロードされたバイト ストリームが現在の JVM の要件を満たしており、仮想マシン自体のセキュリティを危険にさらさないことを確認します。

ファイル形式の検証:

  •  マジックナンバー 0xCAFEBABE で始めるかどうか
  • メジャー バージョン番号とマイナー バージョン番号が現在の仮想マシンの処理範囲内にあるかどうか
  • 定数プール内の定数が定数をサポートしていない型を持っているかどうか (定数タグ フラグを確認してください)
  • 定数を指すさまざまなインデックス値のいずれかが、存在しない定数、または型に準拠しない定数を指しているか
  • CONSTANT_Utf-8_infoの定数にUTF8エンコーディングに準拠していないデータはありませんか?
  • Class ファイル内の各部分セット ファイル自体に削除される追加情報があるかどうか

        この段階の検証に合格した後にのみ、バイト ストリームはメモリのメソッド領域に入り、保存されます。次の 3 つの検証段階はすべてメソッド領域の保存構造に基づいており、バイト ストリームは直接保存されません。操作された。

メタデータの検証:

  • クラスに親クラス (java.lang.object 以外) があるかどうか
  • このクラスの親クラスが継承を許可されていないクラス(最終変更クラス)を継承していないか
  • このクラスが抽象クラスではない場合、その親またはインターフェイスに実装する必要があるすべてのメソッドを実装しているかどうか
  • クラス内のフィールドやメソッドが親クラスと競合していないか(親クラスの最終フィールドのオーバーライド、仕様に準拠しないオーバーロード)

この段階では主に、クラスのメタデータ情報に対してセマンティック検証を実行して、Java 仕様に準拠していないメタデータ情報がないことを確認します。

バイトコード検証:

  • オペランド スタックのデータ型と命令コード シーケンスが常に連動することを確認します (long 型に従って int 型データが読み取られるようには見えません)。
  • ジャンプ命令がメソッド本体の外のバイトコード命令にジャンプしないようにする
  • メソッド本体の型変換が有効であることを確認します (サブクラス オブジェクトを親クラスのデータ型に割り当てることは安全であり、その逆も同様です)。

        これは、検証プロセスの中で最も複雑な段階です。主な目的は、データ フローと制御フローの分析を通じて、セマンティクスが正当かつ論理的であることを判断することです。この段階では、クラスのメソッド本体が検証および分析され、検証されたクラスのメソッドは、実行時に仮想マシンのセキュリティを危険にさらすイベントは発生しません。

シンボル参照の検証:

  • シンボル参照内の文字列で記述された完全修飾名で、対応するクラスを見つけることができるかどうか
  • シンボル参照内のクラス、フィールド、メソッドに現在のクラスがアクセスできるかどうか

準備する:

        このステージではクラスにメモリを確保し、クラス変数の初期値をデフォルト値に設定します メモリはメソッド領域に確保されます(インスタンス変数を除く、クラスの静的変数のみが確保されます)

解析:

        JVM は、定数プール内のシンボリック参照 (ターゲットを記述するために使用されるリテラルのセット、つまり静的プレースホルダー) を直接参照 (メモリ内のターゲットへの直接のポインター、相対オフセット、またはターゲットを間接的に配置するハンドル) に置き換えます。 、分析は主にクラスまたはインターフェイス、フィールド、クラスメソッド、メソッドタイプなどに対して行われます。

初期化:この段階では、クラス内の Java コードが実際に実行され、クラスの静的変数に設定された初期値が与えられます。

使用:クラスが初期化されると、インスタンスの作成、クラスのメソッドの呼び出し、クラスのフィールドへのアクセスなどを含めて使用できるようになります。

アンインストール:

        クラスが役に立たないと判断された場合(クラスのすべてのインスタンスが回復され、クラスをロードしたクラスローダーが回復され、クラスに対応する java.lang.Class オブジェクトがどこからも参照されていない)、アンインストールされる

8. 分散トランザクションの一般的なソリューション

       分散トランザクションとは、複数のデータベース間トランザクションのトランザクションの一貫性の問題、または分散アーキテクチャの下で複数のアプリケーション ノードで構成される複数のトランザクション間のトランザクションの一貫性の問題を指します。現在主流の分散トランザクション ソリューションには、次の 2 つのオプションがあります。

  • 1 つは、XA プロトコルに基づく強力な整合性トランザクション ソリューションです。Amitikos と Seata の XA トランザクション モデル 2PC (CAP 理論に基づいて、分散トランザクションの強力な整合性を確保したい場合、必然的にパフォーマンスがもたらされることがわかります)したがって、一貫性の高いトランザクションのパフォーマンスは比較的低くなります)
  • もう 1 つは、BASE 理論に基づく弱整合性トランザクション ソリューションです。TCC トランザクション モデル、信頼性メッセージに基づく結果整合性スキーム、Seata の Saga トランザクション モデル (最終整合性トランザクションは、非同期によってデータの強い整合性を失います。補償方法により、データの最終整合性が達成されます)。そのため、パフォーマンスが向上し、同時実行性が高いシナリオにより適しています)

2 フェーズ コミット (2PC): (XA プロトコルに基づく)

        2PC、つまり 2 フェーズ コミットは、分散トランザクションのコミットを準備とコミット/ロールバックの 2 つのフェーズ、つまり準備フェーズとコミット実行フェーズに分割します。準備の準備段階では、参加しているすべてのサブトランザクションのフィードバックを待つ必要があり、データベース リソースのロック時間が長すぎる可能性があります。これは、同時実行性が高く、サブトランザクションのライフ サイクルが長いビジネス シナリオには適していません。 -トランザクション。また、コーディネーターがダウンすると、すべての参加者はコミットまたはロールバックの指示を受信しなくなります。

3 フェーズコミット (3pc):

        3フェーズ コミットは、CanCommit、PreCommit、および doCommit です。3PC はタイムアウト メカニズムを使用して 2PC の同期ブロッキング問題を解決し、リソースが永続的にロックされることを回避し、トランザクション プロセス全体の信頼性をさらに高めます。ただし、3PC も同様のダウンタイムの問題には対処できませんが、複数のデータ ソースでデータの不整合が発生する可能性は低いです。

取引補償 (TCC):

        TCC は補償メカニズムを採用しており、その中心的な考え方は次のとおりです。各操作に対して、対応する確認を登録する必要があります。

および補正(アンドゥ)操作。試行、確認、キャンセルの 3 つのフェーズに分かれています。
  • try フェーズ: 実行を試み、すべてのビジネスの整合性チェックを完了し、必要なビジネス リソースを確保します。
  • 確認ステージ: このステージでは、試行ステージがすでにチェックされており、確認ステージではデフォルトで間違いが発生しないため、ビジネスは検査なしで確認および送信されます
  • キャンセル フェーズ: ビジネスの実行が失敗した場合は、このフェーズに入ります。試行フェーズで占有されていたすべてのビジネス、確認フェーズで実行されたすべての操作がロールバックされます。

        TCC スキームを使用すると、アプリケーションはデータベース操作の粒度をカスタマイズできるため、ロックの競合が減少し、パフォーマンスが向上します。ただし、アプリケーションは非常に侵入的であり、試行、確認、キャンセルの 3 つの段階ではビジネス ロジックの実装が必要です。

ローカル メッセージ テーブル (非同期的に確保):

        メッセージプロデューサーは追加のメッセージテーブルを作成し、メッセージ送信ステータスを記録する必要があります。メッセージ テーブルとビジネス データはトランザクションで送信する必要があります。つまり、データベース内に存在する必要があります。その後、メッセージは MQ を通じてメッセージのコンシューマに送信されます。メッセージの送信に失敗した場合は、再試行されます。
        メッセージ コンシューマはメッセージを処理し、独自のビジネス ロジックを完了する必要があります。このとき、ローカルトランザクションの処理が成功すれば処理が成功したこととなり、処理に失敗した場合はリトライされる。ビジネス障害の場合は、ビジネス補償メッセージをプロデューサーに送信して、ロールバックなどの操作を実行するようにプロデューサーに通知できます。
        プロデューサとコンシューマは定期的にローカル メッセージ テーブルをスキャンし、未処理のメッセージまたは失敗したメッセージを再送信します。信頼性の高い自動調整および補充ロジックがある場合、このソリューションは依然として非常に実用的です。
        このスキームは BASE 理論に従い、最終整合性を採用しており、これらのスキームの中でも実際のビジネス シナリオにより適しており、2PC のような 複雑な実装 はありません ( 呼び出しチェーンが非常に長い場合、2PCの可用性は高くなります)。非常に低い) 、TCC のような確認やロールバックの可能性はありません。
利点: 分散トランザクションを回避し、最終的な整合性を実現する非常に古典的な実装です。.NET には既製のソリューションがあります
短所: メッセージ テーブルはビジネス システムに結合されるため、パッケージ化されたソリューションがない場合は、処理する必要がある多くの雑務が発生します。

MQ トランザクション メッセージ:

        RocketMQなど、一部のサードパーティ MQ はトランザクション メッセージをサポートしています。トランザクション メッセージをサポートする方法は、採用されている 2 フェーズ コミットと似ていますが、市場の一部の主流 MQ は、RabbitMQKafkaなど、トランザクション メッセージをサポートしていません。 。

        Ali の RocketMQ ミドルウェアを例に挙げると、そのアイデアはおおよそ次のとおりです。
        Prepared メッセージの最初の段階では、メッセージのアドレスが取得されます。第 2 ステージはローカル トランザクションを実行し、第 3 ステージは第 1 ステージで取得したアドレスを使用してメッセージにアクセスし、状態を変更します。つまり、ビジネス メソッドでは、メッセージ キューに 2 つのリクエスト (メッセージの送信用とメッセージの確認用) を送信するとします。確認メッセージの送信に失敗した場合、RocketMQ は メッセージ クラスター内のトランザクション メッセージを定期的にスキャンします。この時点で Prepared メッセージが見つかった場合は、メッセージの送信者に確認するため、プロデューサーはチェック インターフェイスを実装する必要があります。 RocketMQ は 送信者によって設定されたポリシーに従います。ロールバックするか、確認メッセージの送信を続行するかを決定します。これにより、ローカル トランザクションと同時にメッセージ送信が成功または失敗することが保証されます。
         残念ながら、 RocketMQ には .NETクライアント がありません
利点: 最終的な整合性を実現し、ローカル データベース トランザクションに依存する必要がありません。
短所: 実装が難しく、主流の MQ がサポートしていない、 .NETクライアント がない RocketMQトランザクション メッセージの一部のコードはオープン ソースではありません。

 サーガモード:

  • Saga は、長時間実行されるトランザクションを一連の小さなトランザクション (Saga ステップと呼ばれます) に分割する補償操作に基づく分散トランザクション モデルです。
  • 物語の各ステップには独自の補正操作があり、前の操作を元に戻します。
  • ステップが失敗した場合、システムは逆のアクションを実行して前のステップをロールバックするか、補償アクションを実行して問題を解決します。

        注文処理や航空券の予約など、複雑で長時間にわたるトランザクションに適しています。

        Saga モデルは柔軟性が高く、エラーが発生したときにシステムが単にロールバックするのではなく、適切なアクションを実行できるようにします。

9. 士郎認定プロセス

  • システムは、サブジェクト本体のログイン メソッドを呼び出して、認証のためにユーザー情報トークンを SecurityManager オブジェクトに送信します。
  • SecurityManager は認証操作をオーセンティケーター オブジェクト Authenticator (認証マネージャー) に委任し、認証マネージャーには認証戦略 Authentication Strategy (認証方法) があります。
  • Authenticator は ID 情報を Realm に渡します (データのロードとカプセル化を完了します)。
  • レルムはデータベースにアクセスしてユーザー情報を取得し、情報をカプセル化して認証マネージャー Authenticator に返します。
  • オーセンティケータは、レルムから返された情報を認証します (ユーザーが入力した情報とデータベースでクエリされた情報を比較します)。

10. SpringMVC処理リクエスト処理

  1. ユーザーがリクエストを開始すると、リクエストはまずサーブレットによってインターセプトされ、Spring MVC フレームワークに転送されます。
  2. Spring MVC の DispatcherServet コア コントローラーはリクエストを受信し、ハンドラー マッパー HandlerMapping に転送します。
  3. HandlerMapping は、リクエストを解析し、リクエスト情報と設定情報に従って一致するコントローラー クラスを見つける役割を果たしますが、ここでインターセプターが設定されている場合は、インターセプター内の preHandle メソッドが順番に実行されます。
  4. 一致するコントローラーを見つけたら、リクエスト パラメーターをコントローラーのメソッドに渡します。
  5. コントローラーのメソッドが実行されると、ModeAndView が返されます。これには、ビュー名とビューに渡す必要があるモデル データが含まれます。
  6. ビュー リゾルバーは名前に従ってビューを見つけ、データ モデルをビューに入力して Html コンテンツとしてレンダリングし、クライアントに返します。

おすすめ

転載: blog.csdn.net/LB_bei/article/details/132608625