SpringCloud Alibaba - FeignClient に基づいて Sentinel を統合し、「スレッド分離」と「サーキット ブレーカーの劣化」を実現します

目次

1. FeignClient は Sentinel を統合します

1.1. 統合の理由

1.2. 実装手順

1.2.1. OrderService の application.yml ファイルを変更する

1.2.2. FeignClient の失敗後のダウングレード ロジックの作成

2. スレッドの分離

2.1. スレッド分離の 2 つの方法

2.1.1. スレッドプールの分離

2.1.2. セマフォの分離 (Sentinel のデフォルトの方法)

2.2. スレッド分離の実装 (バルクヘッド モード)

a) フロー制御ルールを追加する

b) テストに JMeter を使用する

c) 分析結果

3. サーキットブレーカーのダウングレード

3.1. サーキットブレーカーの劣化とは何ですか?

3.2. サーキットブレーカー戦略 - スローコール

a) Sentinel でのリモート呼び出しのダウングレード ルールを追加します。

b) ブラウザを継続的に更新し、結果を分析する

3.3. サーキットブレーカー戦略 - 異常の割合と例外の数

a) Sentinel でのリモート呼び出しのダウングレード ルールを追加します。

b) ブラウザを継続的に更新し、結果を分析する


1. FeignClient は Sentinel を統合します


1.1. 統合の理由

前に学んだ電流制限により、同時実行性の高さによって引き起こされるサービス障害は回避できますが、他の理由でサービスが失敗する可能性は依然としてあり、これらの障害を制御して雪崩を回避したい場合は、スレッドの分離とサーキット ブレーカーの劣化に依存する必要があります。

ただし、スレッド分離でもサーキット ブレーカーのダウングレードでも、クライアント (呼び出し元) が保護され、サービスの呼び出し元が障害のあるサービスによってダウンするのを防ぐため、マイクロサービスがリモート呼び出しを開始するときに分離して隔離する必要があります。. ダウングレード、つまり Feign を介して Sentinel を統合し、分離してダウングレードします。

1.2. 実装手順

1.2.1. OrderService の application.yml ファイルを変更する

application.yml で Feign の Sentinel 機能を有効にします。

feign:
  sentinel:
    enabled: true # 开启Feign的Sentinel功能

1.2.2. FeignClient の失敗後のダウングレード ロジックの作成

ダウングレード ロジックを実装する 2 つの方法を次に示します。

  1. FallbackClass: リモート呼び出し例外を処理できません。
  2. FallbackFactory: リモート呼び出しの例外を処理できます。

ここでは 2 番目の方法を選択します。具体的な実装は次のとおりです。

a) feign-api プロジェクトのUserClientFallbackFactory クラスをカスタマイズし、FallbackFactory インターフェイスを実装します。

@Slf4j
public class UserClientFallbackFactory implements FallbackFactory<UserClient> {
    @Override
    public UserClient create(Throwable throwable) {
        return new UserClient() {
            @Override
            public User findById(Long id) {
                //记录异常信息
                log.error("查询用户失败!");
                //根据业务需求返回数据,这里返回一个空对象
                return new User();
            }
        };
    }
}

b) feign-api プロジェクトの設定クラスに、  UserClientFallbackFactory を Bean として登録します。

    @Bean
    public UserClientFallbackFactory userClientFallbackFactory() {
        return new UserClientFallbackFactory();
    }

c) feign-api プロジェクトの UserClient インターフェイス (feign リモート呼び出しインターフェイス) で UserClientFallbackFactor を使用します。

@FeignClient(value = "userservice", fallbackFactory = UserClientFallbackFactory.class)
public interface UserClient {

    @GetMapping("/user/{id}")
    User findById(@PathVariable("id") Long id);

}

2. スレッドの分離


2.1. スレッド分離の 2 つの方法

2.1.1. スレッドプールの分離

スレッド分離とは、各ビジネスを独立したスレッド プールに分割して分離を実現することです。

たとえば、現在 3 つのサービス a、b、c があり、a は b に依存してビジネスを形成し、a は c に依存してビジネスを形成すると、スレッド プール分離により、各ビジネスが実行するサービスのスレッド プールが作成されます。つまり、ここでは 2 つのスレッド プールが作成され、1 つは b 用、もう 1 つは c 用です。リクエストが a に到着すると、リクエスト自体のスレッドは使用されませんが、スレッドはこれら 2 つのプールからフェッチされます現時点では、このスレッドは Feign のクライアントを呼び出してリモート呼び出しを開始できます。 

これにより、2 つのサービスが分離されます。サービス b が失敗した場合、サービス b が行うことは、そのプール内のスレッドを使い果たすことだけです。新しいリクエストがある場合でも、このサービスにアクセスしたいと考えますが、プールはいっぱいです。彼はまだ来られますか?で?このようにして、サービス a のリソースが枯渇することはありません。

アドバンテージ

1. アクティブ タイムアウトのサポート:スレッド プール モードでは、リモート呼び出しごとに独立したスレッドが割り当てられます。つまり、スレッド プールを介して制御できます。リクエストに時間がかかることが判明した場合、スレッドはすぐに終了できます。

2. 非同期呼び出しのサポート:各呼び出しは、最初に Tomcat リクエストを処理したスレッドではなく、スレッド プールによって割り当てられた独立したスレッドです。また、異なるサービスには異なるスレッド プールがあるため、特定のサービスに対して処理されたリクエストを同時に実行できます。リモート呼び出しは他のサービスのために処理されます。

欠点がある

1. スレッドの追加オーバーヘッドは比較的大きくなります。各呼び出しには独立したスレッドがあります。スレッドが増えるほど、オーバーヘッドも大きくなります。他とは別に、CPU コンテキストの切り替えだけでも時間がかかります。

該当シーン

1. 「低ファンアウト」に適しています:低ファンアウトとは、他のサービスに依存するサービスがあることを意味します。依存するサービスが多いほど、ファンアウトは高くなります。各リモート呼び出しには独立したスレッドがあるため、マルチスレッドのオーバーヘッド問題を回避するため、ファンアウトの低いシナリオに適しています。

2.1.2. セマフォの分離 (Sentinel のデフォルトの方法)

セマフォは前述のセマフォに相当します。

たとえば、サービス a とサービス b があり、サービス a はサービス b に依存しています。a が要求されると、セマフォは独立したスレッドを作成しませんが、最初に要求を処理したスレッドを使用して Feign を直接呼び出します。 、彼はどのようにして孤立を達成したのでしょうか?カウンターを整備しており、リクエストが来るたびにカウンターにものが残っているかどうかを判断している。 

たとえば、カウンタの合計は 10 です。リクエストが入力されるたびにカウンタは 1 ずつ減少し、リクエストが処理されるとカウンタは 1 ずつ増加します。同時にアクセスするリクエストが 10 個ある場合、カウンタは 1 ずつ増加します。 、10 個の信号がすべて取得されており、この時点で別のリクエストがある場合、新しいリクエストは直接拒否されるため、障害分離の役割も果たすことができます。

アドバンテージ

1. 軽量で追加のオーバーヘッドなし: これは単なるカウンターであり、スレッドを開始する必要がないため、実際にはスレッド プールを補います。

欠点がある

1. アクティブ タイムアウトはサポートされていません: リクエストが到着すると、セマフォがあるかどうかだけが判断され、ある場合はセマフォが割り当てられますが、セマフォは制御不能であり、途中で停止することはできません。 Feign 自体のタイムアウト時間であるため、アクティブなタイムアウトは実行できません。

2. 非同期呼び出しはサポートしません。非同期呼び出しはもちろん、独立したスレッドもありません。

該当シーン

1. 高頻度の呼び出し、高ファンアウト: セマフォのオーバーヘッドが低いため、ゲートウェイは高ファンアウトのシナリオです。リクエストをさまざまなマイクロサービスにルーティングします。ファンアウトは非常に大きいため、ゲートウェイは基本的にセマフォ モードが使用されます (これが、sentinel がセマフォ モードに適している理由です)。

2.2. スレッド分離の実装 (バルクヘッド モード)

Sentinel コンソールでは、フローファースト ルールを追加するときに、次の 2 つのしきい値タイプから選択できます。

  • QPS: 前に示した 1 秒あたりのリクエスト数。
  • スレッド数: このリソースで使用できる Tomcat スレッドの最大数 スレッド数を制限することで、バルクヘッド モードが実装されます。

 

以下にケースのデモンストレーションを示します。UserClient のクエリ ユーザー インターフェイスにフロー制御ルールを設定します。スレッド数は 2 を超えることはできません。

FeignClient は Sentinel を統合し、クエリ順序リソースにアクセスするように構成されているため、Sentinel で次のリモート呼び出しリソースを確認できます。

a) フロー制御ルールを追加する

b) テストに JMeter を使用する

c) 分析結果

結果ツリーでは、すべてのリクエストが成功したことがわかります。これは、Feign に基づいて Sentinel 保護メカニズムが統合されており、その保護戦略が「例外ログを出力し、空のオブジェクトを返す」であるためです。

最初のいくつかのリクエストは正常に情報を返しましたが、後続のリクエストはすべて空のオブジェクトを返したことがわかります。これは、Sentinel の構成されたばかりのフロー制御メカニズムがトリガーされたためです。

IDEA のログの印刷出力も確認できます。

3. サーキットブレーカーのダウングレード


3.1. サーキットブレーカーの劣化とは何ですか?

サーキット ブレーカーのダウングレードとは、サービス呼び出し時に短絡デバイスを使用して「異常比率、低速呼び出し比率、例外数」の統計を収集することです。たとえば、統計が異常比率の場合、異常比率の場合、高すぎるとしきい値がトリガーされると、サービスが停止します。このようにして、障害が発生したサービスは隔離されます。

これは、古代の武道家が毒蛇に手を噛まれたときに、毒が全身に広がらないようにとっさにナイフを振り上げて手を切り落とすようなものですが、手を切るのは技術ではありません。それを取り返すことができるのが本当のスキルです。

Sentinel は、サービスが復元されたときにサーキット ブレーカーにサービスへのアクセス要求を解放させることができます。

具体的には、ヒューズには次の 3 つの状態があります。

3.2. サーキットブレーカー戦略 - スローコール

呼び出しが遅いとは、応答時間が長すぎて指定時間を超えている場合、リクエストは非常に遅いと見なされ、追加のリソースを占有し、サービス全体の速度が低下することを意味します。

したがって、遅い呼び出しの割合がしきい値に達すると、つまりサービスを呼び出すたびに非常に遅い場合、サーキット ブレーカーがトリガーされます。

Sentinel コンソールには新しいダウングレード ルールが存在する可能性があります。たとえば、サーキット ブレーカーがトリガーされるタイミングについては次のとおりです。

解釈: RT (ResponseTIme 応答時間) が 500 ミリ秒を超える場合、それは遅い呼び出しです。最後の 10000 ミリ秒以内のリクエストをカウントします。遅い呼び出しの比率が 0.5 を超える場合、サーキット ブレーカーがトリガーされます。サーキット ブレーカーは通常 5 秒です。テスト用に 1 つのリクエストを解放します。

ここでは、UserClient クエリ ユーザー インターフェイスの劣化ルールを設定します。RT は 50 ミリ秒、統計時間は 1 秒、リクエストの最小数は 5、障害しきい値比は 0.4、サーキット ブレーカーの継続時間は 5 秒です。 。

注: ここで低速呼び出しルールをトリガーするために、UserService のビジネスを変更してビジネス時間を増やしました。

a) Sentinel でのリモート呼び出しのダウングレード ルールを追加します。

クラスターポイントリンクで設定できます。

ルールは次のとおりです

b) ブラウザを継続的に更新し、結果を分析する

数回簡単に更新すると、サーキット ブレーカーが発生し、ダウングレード戦略がトリガーされたことがわかります。これは、空のユーザー情報が返されることを意味します。

リクエストを送信してから 5 秒後に、ハーフオープン モードに入っていることがわかり、テストする機会が与えられます。

3.3. サーキットブレーカー戦略 - 異常の割合と例外の数

異常比率:指定期間内にコール数が指定リクエスト数に達し、発生した例外が設定比率を超えた場合にカウントされ、サーキットブレーカーが作動します。

例外の数 (例外率に似ていますが、ここでは示されていません): 名前が示すように、指定されたリクエスト数に達し、例外しきい値 (サーキット ブレーカー) を超えた場合に、指定された期間内の呼び出し数をカウントします。トリガーされます。

例えば:

解釈: 過去 1000 ミリ秒間のリクエストをカウントし、リクエスト数が 10 回を超え、異常率が 0.5 以上の場合、サーキット ブレーカーが作動し、サーキット ブレーカー時間が 5 秒になります。

ここでは、異常な比率を示すためにケースを使用します。UserClientクエリ ユーザー インターフェイスの劣化ルールを設定します。統計時間は 秒、リクエストの最小数は 、障害しきい値比率は 0.4  、サーキット ブレーカーの継続時間は 5秒

例外統計をトリガーするために、例外をスローするように UserService のビジネスを変更したことに注意してください。

a) Sentinel でのリモート呼び出しのダウングレード ルールを追加します。

b) ブラウザを継続的に更新し、結果を分析する

5 回連続してリフレッシュすると、サーキット ブレーカーがトリガーされたことがわかります。

5 秒後に回復します。ここでは、リモート呼び出し元も id = 1 のユーザーを取得できるように、リクエストを /order/101 に変更する必要があります。それ以外の場合は、引き続き /order/102 リクエストを使用し、リモート呼び出し元は id = になります。 2は引き続き例外が発生し、半開状態のままですが、ヒューズオープン状態に戻りました。

 

おすすめ

転載: blog.csdn.net/CYK_byte/article/details/133486023