Josh Long によるbootiful-microservice プロジェクトで遊んでいます。(ブリクストンサブプロジェクト)
予約サービスでは、負荷をシミュレートするために構成可能な時間だけスリープできる単純なステータス メソッドを追加しました。
@RequestMapping(method = RequestMethod.GET, value = "/status")
public String status(){
System.out.println("Checking status");
try {
Thread.sleep((long) (rand.nextDouble()*sleepTime));
} catch (InterruptedException e) {
e.printStackTrace();
}
return "All is good";
}
sleepTime
変数は Spring Config Server からプルされます
予約クライアントで、ゲートウェイにエントリ ポイントを追加しました。
@FeignClient("reservation-service")
interface ReservationReader {
@RequestMapping(method = RequestMethod.GET, value = "/reservations")
Resources<Reservation> readReservations();
@RequestMapping(method = RequestMethod.GET, value = "/status")
String status();
}
}
そして私はHystrixCommand
@HystrixCommand(fallbackMethod = "statusFallback")
@RequestMapping(method = RequestMethod.GET, value = "/status")
public String status(){
return reader.status();
}
public String statusFallback(){
return "Bad";
}
これはすべてうまくいきます。
一部のリクエストが Hystrix のデフォルトのしきい値 (1000 ミリ秒) を超えるように、スリープ時間を 1500 ミリ秒に設定しました。
API にアクセスし始めると、タイムアウトが原因でいくつかのエラーが発生します。私が十分に長く打つと(50回はうまくいくようです)、サーキットブレーカーがトリガーされ、サーキットが開きます:
私の理解では、ダウンストリーム サービスが再び正常になると、Hystrix は 1 つの呼び出しをルーティングし、それをヘルス チェックとして使用しようとします。呼び出しが成功した場合、回線は再び閉じられる必要があります。
しかし、これはここでは起こっていません。スリープ時間をより小さな値 (500ms としましょう) に変更した後でも、回路は開いたままになります。私の呼び出しは予約サービスにルーティングされず、すべての呼び出しでフォールバックが使用されます。回線を再び閉じる唯一の方法は、予約クライアント サービスを再起動することです。
私は何か見落としてますか?Hystrixの問題ですか?または、Spring Integration を使用しますか?
アップデート
さらにテストを行ったところ、スリープが減少した後でも回路が永久に閉じたままになることが確認できました。
ただし、Zuul 構成でルートを使用すると、期待どおりの動作が得られます。タイムアウトしない要求を検出すると、回路は閉じます。
Spring で手動で行う場合と比較して、ルートによる転送の別の違いに気付きました。フィルターを作成すると、クライアントで /status/ を呼び出してもフィルターがトリガーされません。ルートをセットアップすると (例: /foos/status => /status)、フィルターがトリガーされ、Hystrix が適切に動作します。
それはSpringのバグですか?