HystrixとSentinelをコード例で使用

本記事シリーズでは、**Alibaba**のオープンソースの**Sentinel Java**フローコントロールプロジェクトを**Hystrix**と比較しながらご紹介します。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/hystrix-vs--sentinel-a-tale-of-two-circuit-breakers-part-2_594756)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

前回のブログでは、2つのライブラリを高いレベルで比較しました。今度は、コード例を見ながら、両者の使い方を見ていきましょう。

#例
ここで使用した例は、このSpringの[チュートリアル](https://spring.io/guides/gs/circuit-breaker/?spm=a2c65.11461447.0.0.7e4717c6AVEkbf)のものです。有名な書店のサンプルアプリです。

始める前に、サンプルアプリをダウンロードして設定するために、元のドキュメントの手順に従っていることを確認してください。

サンプルは少し修正を加えて再利用することができます。Sentinelは最新のSpring Frameworkのリリースの一部です。そのため、追加の依存関係の変更はありません。

直接 `read/src/main/java/hello/BookService.java` に移動して、以下のコードを貼り付けてみましょう。

```
@Service
public class BookService {
  private final RestTemplate restTemplate;
  public BookService(RestTemplate rest) {
    this.restTemplate = rest;
  }
  @SentinelResource(value = "readingList", fallback = "reliable")
  public String readingList() {
    URI uri = URI.create("http://localhost:8090/recommended");
    return this.restTemplate.getForObject(uri, String.class);
  }
  public String reliable() {
    return "Cloud Native Java (O'Reilly)";
  }
}
```

ご覧のように、`@HystrixCommand`アノテーションを`@SentinelResource`に置き換えただけです。`value`属性は、サーキットブレーカーに適用したいメソッドのラベルを付けます。そして、`fallback`属性は、`fallbackMethod`関数を指し示します。そして、`fallback` 関数 `reliable()` を追加します。この関数は、例と同じことをします。

ここまでは、Hystrixがやっていることにかなり近いです。しかし、前回の記事で述べたように、サーキットブレーカーの動作はHystrixが指示しています。リソースを指摘したら、サーキットブレーカーを起動させる条件は、その通りに処理されています。

一方、Sentinelはその制御をユーザーに委ねているため、ユーザーはその条件を定義するためのルールを作成しなければなりません。それを実行して、ルールを追加してみましょう。ファイルの最後に追加することができます。

```
DegradeRuleManager.loadRules(Collections.singletonList(
    new DegradeRule("readingList") // resource name
        .setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO) // strategy
        .setCount(0.5) // threshold
        .setTimeWindow(10) // circuit breaking timeout (in second)
));
```

先ほど`DegradeRule`を作成し、モードを例外率、しきい値を0.5（2のうち1）、回復時間を10秒に設定しました。`DegradeRuleManager`はこのルールをロードして有効にします。

実際に試してみましょう。読書サービスのみを起動し、書店サービスは起動しません。そのため、リクエストが来るたびに失敗します。2回の試行（そして2回の失敗）の後、フォールバック機能が有効になるのを見てみましょう。

```
Cloud Native Java (O'Reilly)
```

では、Bookstoreのサービスを開始してみましょう。10秒後、通常のレスポンスを見ることにします。

```
Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)
```

本番環境では、コード経由でルールを追加するよりも、Sentinelダッシュボードを使用してこのルールを設定する方が実際には簡単です。以下はスクリーンショットです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/9a9c2cf3-d81a-27f0-bbaf-ee37b5ce1f30.png)


#更に
ここまでは、Hystrixが実行したのと同じ機能を見てきました。そして実際には、Sentinelにはもう一歩が必要です。では、例を見てみましょう。

Sentinelでは、異なるメトリクスに基づいてルールを設定することができます。この例では、QPSを使用しています。

まず、メインクラス`bookstore/src/main/java/hello/BookstoreApplication.java`を探してみましょう。

```
@RestController
@SpringBootApplication
public class BookstoreApplication {
    private static final Logger LOGGER = LoggerFactory.getLogger(BookstoreApplication.class);
    @SentinelResource(value = "readingList", blockHandler = "handleTooManyRequests")
    @RequestMapping(value = "/recommended")
    public String readingList(){
        return "Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)";
    }
    public String handleTooManyRequests(BlockException ex) {
        LOGGER.error("Too many requests: " + ex.getClass().getSimpleName());
        return "Sentinel in Action";
    }
  public static void main(String[] args) {
    SpringApplication.run(BookstoreApplication.class, args);
  }
```

`@SentinelResource`を追加しましたが、`フォールバック`関数の代わりに`blockHandler`関数を使用しています。この関数は、単に "Sentinel in Action" というメッセージを出力します。さて、この関数がトリガーされるときの新しいルールを追加する必要があります。

```
FlowRule rule = new FlowRule("readingList")
    .setCount(1);
FlowRuleManager.loadRules(Collections.singletonList(rule));
```

このルールは、1 秒間に 1 つ以上のリクエストがある場合に適用されます。このコードの一部は、ファイルの最後に追加することができます。

我々が`BookStore`サービスを開始した後、最初のリクエストで、我々は通常の応答を取得しなければなりません。

```
Spring in Action (Manning), Cloud Native Java (O'Reilly), Learning Spring Boot (Packt)
```

しかし、1秒間に1つ以上のリクエストを生成した場合は、`blockHandler`関数がキックインするのを見なければなりません。

```
Sentinel in Action
```

そして、1秒後には再び正常な反応が見られます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/242e99c0-3e8c-2bf8-a819-b11d1a1c824c.png)

ここでも、実際の運用環境では、ユーザーはダッシュボードを使用してトラフィックを構成し、監視することができます。

#要約
Sentinelは、サービスへのフローを制御するための複数のオプションをユーザーに提供することを目的としています。そうすることで、ユーザーがGUIやコードを介してルールを定義する必要があります。QPS以外にも、ユーザーはスレッド数を制御したり、アクセス制御のためのホワイトリストを作成したりすることができます。分散サービスの複雑化が進む中で、このモデルはユーザーの要求をよりよく満たすものとなるでしょう。

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*