Spring Cloud の概要と負荷分散リボンとサービスのフォールトトレラントな Hystrix コンポーネントの詳細な説明

Spring Cloudの概要

公式ウェブサイト

序章

Spring Cloud は、Spring Boot に基づくマイクロサービス アーキテクチャ開発フレームワークです。構成管理、サービス ガバナンス、サーキット ブレーカー、インテリジェント ルーティング、マイクロ エージェント、制御バス、グローバル ロック、意思決定キャンペーン、分散セッション、マイクロサービス アーキテクチャに関わるクラスター状態管理などの操作のためのシンプルな開発方法を提供します。

Spring Cloud は、以下で説明するように、複数のサブプロジェクト (分散システムに関与するさまざまなオープンソース製品用であり、新しいものを追加する場合もあります) で構成されます。

  • Spring Cloud Config: Git を使用した構成コンテンツの保存をサポートする構成管理ツール。アプリケーション構成の外部ストレージの実装に使用でき、クライアント構成情報の更新、構成コンテンツの暗号化/復号化などをサポートします。

  • Spring Cloud Netflix: 複数の Netflix OSS オープンソース スイートを統合するコア コンポーネント

    • Eureka: サービス レジストリ、サービス登録、および検出メカニズムの実装を含むサービス ガバナンス コンポーネント。
    • リボン: クライアント負荷分散のサービス呼び出しコンポーネント。
    • Hystrix: サーキット ブレーカー パターンを実装するフォールト トレラントな管理コンポーネントで、サービス依存関係の遅延を軽減し、障害に対する強力なフォールト トレランスを提供します。
    • Feign: リボンと Hystrix に基づく宣言型サービス呼び出しコンポーネント。
    • Zuul: インテリジェント ルーティングやアクセス フィルタリングなどの機能を提供するゲートウェイ コンポーネント。
  • Spring Cloud Bus: イベント、メッセージ バス。クラスター内の状態変更やイベントを伝播して、構成の動的更新などの後続の処理をトリガーするために使用されます。


リリースノート

Spring Cloud は、Spring コミュニティの他のプロジェクトとは異なり、比較的独立していません。多くのサブプロジェクトを持つ大規模で包括的なプロジェクトです。マイクロサービス アーキテクチャ ソリューションの包括的なスイートであると言えます。含まれる各サブプロジェクトも独立して更新および反復されており、それぞれが独自のリリース バージョン番号を維持しています。したがって、Spring Cloud の各バージョンには、異なるバージョンの複数のサブプロジェクトが含まれることになりますが、各バージョンのサブプロジェクトのリストを管理し、Spring Cloud のバージョン番号とそのサブプロジェクトのバージョン番号の混同を避けるために、バージョン番号は使用されず、命名方法が使用されます。

これらのバージョンの名前は、ロンドンの地下鉄の駅名を採用しており、最初にリリースされたバージョンは Angel、2 番目にリリースされたバージョンは Brixton というように、アルファベット順にバージョンの年代順に対応しています。

Spring Cloud プロジェクトのバージョンのリリース コンテンツが重要な点まで蓄積されるか、重大なバグ解決策が利用可能になると、SRX バージョンと呼ばれる「サービス リリース」バージョンがリリースされます。X は増加する数字であるため、Brixton.SR5 は Brixton の 5 番目のリリース バージョンです。

Springクラウドバージョン スプリングブートバージョン
ホクストン 2.2.x
グリニッジ 2.1.x
フィンチリー 2.0.x
エッジウェア 1.5.x
ダルストン 1.5.x

Springcloud と SpringBoot の違い:

  • 効果は異なります:

    • SpringBoot は、アノテーションを使用して XML 構成を簡素化する迅速な開発フレームワークです。組み込みのサーブレット コンテナーがあり、Java アプリケーションとして実行されます。その機能は、デフォルト構成を提供し、構成プロセスを簡素化することです。
    • SpringCloud は SpringBoot に基づくフレームワークのコレクションであり、マイクロサービスの包括的な管理フレームワークを提供します。
  • 別の方法で使用します。

    • SpringBootは単体でも使用可能
    • SpringCloudはSpringBoot前提で使用する必要があります。
  • SpringBoot と SpringCloud はどちらも Spring エコシステムから派生したソフトウェア開発フレームワークですが、本来の目的はまったく異なります。

    • SpringBoot は、構成ファイルを簡素化し、マイクロサービス開発時の作業効率を向上させるように設計されています。
    • Spring Cloud は、同じプロジェクト内のマイクロサービスを管理するように設計されています

    したがって、この 2 つはまったく異なるソフトウェア開発フレームワークです。


負荷分散リボン

リボンはクライアント負荷分散ツールです

実際の環境では、マイクロサービスはクラスタにデプロイされることが多く、サービスリストには複数のインスタンスが存在することになるため、複数のインスタンスリストから選択するための負荷分散アルゴリズムを記述する必要があります。

リボンの設定項目

グローバル設定はリボンを使用します。=

ribbon:
  ReadTimeout: 2500 	# 数据通信超时时长,单位:ms。默认为1000
  ConnectTimeout: 500 	# 连接超时时长,单位:ms。默认为1000
  OkToRetryOnAllOperations: false 	# 是否对所有的异常请求(连接异常和请求异常)都重试。默认为false
  MaxAutoRetriesNextServer: 1 		# 最多重试多少次连接服务(实例)。默认为1。不包括首次调用
  MaxAutoRetries: 0 	# 服务的单个实例的重试次数。默认为0。不包括首次调用
  NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule	# 切换负载均衡策略为随机。默认为轮询策略

サービス構成を指定 <サービス名>.ribbon.=

serverName:	# 单独给某⼀服务配置。serverName是服务名,使⽤的时候要⽤服务名替换掉这个
  ribbon:
    connectTimeout: 5000
    readTimeout: 5000

入門ケース

  1. 依存関係のインポート

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
    
  2. @LoadBalanced アノテーションを RestTemplate の構成メソッドに追加します。

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
          
          
        return new RestTemplate();
    }
    
  3. サービス名で直接呼び出す

    @GetMapping("user/{id}")
    public User getUserById(@PathVariable long id) {
          
          
        String url = "http://user-service" + "/user/" + id;
        User user = restTemplate.getForObject(url, User.class);
        return user;
    }
    

負荷分散の原理

  1. RestTemplate に @LoadBalanced アノテーションを追加した後、LoadBalancerClient を使用して RestTemplate を構成します
  2. Spring Cloud リボンの自動構成クラス LoadBalancerAutoConfiguration の @ConditionalOnBean(LoadBalancerClient.class) 条件が確立されます
  3. LoadBalancerInterceptor が自動構成に追加されます。このインターセプターはリクエストをインターセプトし、サービス ID を通じてサービスのアドレス リストを取得し、ロード バランシング アルゴリズムを通じて呼び出すアドレスを選択します。

ここに画像の説明を挿入


サービス フォールト トレランス Hystrix

コンセプト

サービス障害のなだれの影響:

マイクロサービスアーキテクチャでは業務に応じて個別のサービスに分割し、RPCでサービス同士を呼び出すことができますが、Spring CloudではRestTemplate + LoadBalanceClientとFeignを利用して呼び出すことができます。高可用性を確保するために、通常は単一のサービスがクラスターにデプロイされます。ネットワーク上の理由や独自の理由により、サービスが 100% 利用可能であることは保証できず、単一のサービスに問題がある場合、そのサービスを呼び出すときにスレッド ブロッキングが発生します。サービス間の依存関係、障害は伝播し、マイクロサービス システム全体に壊滅的な重大な結果を引き起こします。これは、サービス障害の雪崩効果です。


サービスのダウングレード:

分散システムでは、複数のサービスを呼び出す際に何らかの「エラー」が発生しますが、これらの「エラー」を適切に処理できないとプロジェクト全体が麻痺してしまいますが、これは絶対にあってはならないことです。したがって、この問題を解決するには、try-catch メカニズムと同様に、エラーが発生すると catch 内のコードが実行されるサービスのダウングレードが必要です。

サーバーへの負荷が急激に増加すると、サーバー リソースを解放し、コア タスクの正常な動作を保証するために、現在のビジネス状況とトラフィックに応じて一部のサービスとページが戦略的にダウングレードされます。

サービスの低下によってリクエストは失敗しますが、ブロッキングは発生しません。影響を受けるのは、依存するサービスに対応するスレッド プール内のリソースだけであり、他のサービスには応答しません。


サービスヒューズ:

一般に、ソフトウェアシステムにおいて何らかの原因によりサービスに過負荷が生じた場合に、システム全体の障害を防止するために採用される保護手段のことを指し、そのためヒューズを過負荷保護とも呼ぶ場合が多い。多くの場合、最初はシステム内の局所的かつ小規模な障害だけが発生しますが、さまざまな理由により障害の範囲はますます拡大し、最終的には世界的な影響につながります。

分散システムでは、システムを呼び出す際、一定時間内にこのサービスの呼び出しエラー数が一定値に達するとサーキットブレーカーがオンになり、過去の呼び出しではなく直接ダウングレードメソッドが呼び出されます。一定の時間が経過して、通話が行われ、サービスが接続されていることが確認されると、サーキット ブレーカーが「半開」状態に変更され、通話が 1 つずつゆっくりと通過します。エラーがなければ、サーキット ブレーカーが閉じて、すべてのサービスが通過できるようになります。

該当するシナリオ: アプリケーションが失敗する可能性のあるリモート サービスや共有リソースを直接呼び出すことを防止します。


ヒストリックス

Hystrix は、Netflix がオープンソース化した遅延およびフォールトトレラントなライブラリであり、リモート サービスやサードパーティ ライブラリへのアクセスを分離して連鎖的な障害を防ぐために使用されます。

Hystix が雪崩問題を解決する手段には主に次のようなものがあります。

  • スレッドの分離
  • サービスサーキットブレーカー

Hystrix 構成アイテム

hystrix:
  command:
    default:	# 全局默认配置
      execution:	# 线程隔离相关
        timeout:
          enabled: true		# 是否给方法执行设置超时时间,默认为true。一般不改。
        isolation:
          strategy: THREAD	# 配置请求隔离的方式,这里是默认的线程池方式。还有一种信号量的方式semaphore,
          thread:
            timeoutlnMilliseconds: 10000	# 方式执行的超时时间,默认为1000毫秒,在实际场景中需要根据情况设置
      circuitBreaker:	# 服务熔断相关
        requestVolumeThreshold: 10			# 触发熔断的最小请求次数,默认20
        sleepWindowInMilliseconds: 10000	# 休眠时长,单位毫秒,默认是5000毫秒
        errorThresholdPercentage: 50		# 触发熔断的失败请求最小占比,默认50%
    serverName:	# 单独给某⼀服务配置
      execution:
        timeout:
          enabled: true
        isolation:
          strategy: THREAD
          thread:
            timeoutlnMilliseconds: 10000

スレッドの分離

原理

Hystrix は、依存するサービス呼び出しごとに小さな独立したスレッド プールを割り当てます。ユーザーのリクエストはサービスに直接アクセスしなくなり、スレッド プール内のアイドル スレッドを通じてサービスにアクセスします。スレッド プールがいっぱいの場合、呼び出しは直ちに拒否されます。それ以外の場合は、スレッドがリクエストの処理に使用されます。メイン スレッドでタイムアウト期間を設定できます。


入門ケース

  1. 依存関係のインポート

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    
  2. スタートアップ クラスに注釈を追加します。@EnableCircuitBreaker 、ヒューズをオンにします。

    注: アノテーション @SpringCloudApplication = @SpringBootApplication + @EnableDiscoveryClient + @EnableCircuitBreaker の組み合わせ

    // @SpringBootApplication
    // @EnableDiscoveryClient
    // @EnableCircuitBreaker
    @SpringCloudApplication
    public class ConsumerApplication {
          
          
        public static void main(String[] args) {
          
          
            SpringApplication.run(ConsumerApplication.class, args);
        }
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
          
          
            return new RestTemplate();
        }
    }
    
  3. ダウングレードロジックを書く

    対象サービスの呼び出しに失敗した場合はエラー応答が返されます。事前に障害時のダウングレード処理ロジックを記述し、@HystixCommondアノテーションを使用してダウングレード処理方法を指定する必要がある

    @GetMapping("user/{id}")
    @HystrixCommand(fallbackMethod = "getUserByIdFallback")		// 指定降级处理方法
    public User getUserById(@PathVariable long id) {
          
          
        // 使用服务ID替换真实地址
        String url = "http://user-service" + "/user/" + id;
        User user = restTemplate.getForObject(url, User.class);
        return user;
    }
    
    /**
     * 降级逻辑处理方法,方法参数、返回类型与原始方法一致
     */
    private User getUserByIdFallback(long id) {
          
          
        User user = new User(1L,"我是备份",18,new Date());
        return user;
    }
    
  4. 試験結果:

    • 呼び出されたサービスが正常にサービスを提供している場合は、これまでと同様のアクセスとなります。

    • 呼び出されたサービスがダウンしている場合、呼び出しは劣化したロジック処理メソッドの戻り値を返します。


デフォルトのフォールバック

アノテーション @DefaultProperties を使用してクラスにフォールバック構成を追加し、デフォルトのフォールバックを実現できます。

  • デフォルトメソッドの戻り値の型は呼び出し元のメソッドと一致している必要があり、パラメータを含めることはできません
@RestController
@RequestMapping("/consumer")
@DefaultProperties(defaultFallback = "defaultFallback")		// 默认的Fallback
public class ConsumerController {
    
    
    
    @Autowired  // 注入RestTemplate
    private RestTemplate restTemplate;

    @GetMapping("user/{id}")
    @HystrixCommand
    public User getUserById(@PathVariable long id) {
    
    
        // 使用服务ID替换真实地址
        String url = "http://user-service" + "/user/" + id;
        User user = restTemplate.getForObject(url, User.class);
        return user;
    }

    /**
     * 降级逻辑处理方法,方法参数、返回类型与原始方法一致
     */
    private User getUserByIdFallback(long id) {
    
    
        User user = new User(1L,"我是备份",18,new Date());
        return user;
    }
    
    /**
     * 默认降级逻辑处理方法。返回类型必须与调用方法一致,并且不能有参数
     */
    private User defaultFallback(){
    
    
        User user = new User(1L,"我是默认备份",18,new Date());
        return user;
    }
}

サービスサーキットブレーカー

サービス インスタンスへのアクセスに頻繁に失敗する場合は、サービス インスタンスを一時的に分離できます。これはヒューズです。

ヒューズの原理

ヒューズ (サーキットブレーカー)、サーキットブレーカーとも呼ばれます

サーキット ブレーカー自体は、回路を過負荷から保護するために使用されるスイッチング デバイスです。回路内で短絡が発生した場合、「サーキット ブレーカー」は障害のある回路を適時に遮断し、過負荷、発熱、さらには火災などの重大な結果を防ぐことができます。

分散アーキテクチャにおけるサーキット ブレーカー モードの機能は同様で、サービス ユニットに障害が発生した場合 (電化製品の短絡と同様)、長時間待機する代わりに、サーキット ブレーカーの障害監視を通じてエラー応答が呼び出し元に返されます (ヒューズ切れと同様)。これにより、障害が発生したサービスの呼び出しによってスレッドが長時間占有されたり解放されたりすることがなくなり、分散システムにおける障害の拡大が回避されます。

Hystix のヒューズ ステート マシン モデル:

ここに画像の説明を挿入

ステート マシンには 3 つの状態があります。

  • Closed: クローズ状態 (サーキットブレーカーが閉じている)、すべてのリクエストに正常にアクセスできます。

  • オープン: オープン状態 (サーキット ブレーカーがオープン)、すべてのリクエストがダウングレードされます。

    Hystrix はリクエストのステータスをカウントし、一定時間内に失敗したリクエストの割合がしきい値に達すると、ヒューズが作動し、サーキット ブレーカーが完全に開きます。デフォルトの失敗率のしきい値は 50% で、リクエストの数は少なくとも 20 である必要があります。

    一定時間内に合計 19 回のリクエストが失敗したとすると、20 回まではヒューズが切れませんが、20 回を超えて失敗率が 50% を超えた場合、つまり失敗回数が 10 回に達していればヒューズが作動します。

    ヒューズがトリガーされた後、サーキット ブレーカーは一定の統計時間 (デフォルトは 5 秒) の間オープン状態を維持し、この期間中はすべてのリクエストが直接ダウングレードされます。

  • ハーフオープン: ハーフオープン状態。オープン状態は永続的ではなく、オープン後にスリープ時間に入ります (デフォルトは 5 秒)。スリープ時間が経過すると、ブレーカーは自動的に半開状態になります。この時点で、リクエストは解放されて通過し、リクエストが正常であればサーキット ブレーカーは閉じられ、そうでない場合は開いたままとなり、5 秒間のスリープ タイマーが再度実行されます。

サーキットブレーカーがオープン状態になる条件:

  1. リクエストの失敗回数がしきい値に達しました。デフォルトは 20 回です
  2. リクエストの失敗の割合がしきい値に達しました。デフォルトは 50% です。

拡大

SentinelとHystrixの比較

Sentinel は Alibaba ミドルウェア チームによってオープンソース化されています。分散サービス アーキテクチャ向けの軽量で可用性の高いトラフィック制御コンポーネントです。主にトラフィックをエントリ ポイントとして使用し、トラフィック制御、サーキット ブレーカーの低下、システム負荷保護などの多面からユーザーがサービスの安定性を保護できるようにします。

内容を比較する センチネル ヒストリックス
隔離ポリシー セマフォの分離 スレッドプール分離/セマフォ分離
サーキットブレーカーのダウングレード戦略 応答時間または故障率に基づく 故障率に基づく
リアルタイムインジケーターの実装 スライドウィンドウ スライディング ウィンドウ (RxJava ベース)
ルール設定 複数のデータソースをサポート 複数のデータソースをサポート
スケーラビリティ 複数の拡張ポイント プラグインフォーム
注釈ベースのサポート サポート サポート
制限する QPSに基づいて、通話関係に基づいた電流制限をサポート サポートしません
トラフィックシェーピング スロースタート、速度スタビライザーモードをサポート サポートしません
システム負荷保護 サポート サポートしません
コンソール すぐに使用できるルールの設定、第 2 レベルの監視、マシン検出などの表示を行うことができます。 不完全
共通フレームワークへの適応 サーブレット、Spring Cloud、Dubbo、gRPC など サーブレット、Spring Cloud Netflix

おすすめ

転載: blog.csdn.net/footless_bird/article/details/128469102