Zuul、Ribbon、Feign、Hystrix使用時のタイムアウト時間設定の問題
7797 ワード
前に書く
Feign+Hystrixコーディネートモードでのダウングレード(fallback)タイムアウト時間カスタマイズをテストする問題で、ピットを踏んだついでにZuul、Ribbon+Hystrixモードでそれぞれどのように設定するかを調べてみました
これらのものをテストするのに多くの力を費やしました.このいくつかのモジュールが組み合わせて使用されているか、内部が他のモジュールに依存しているか、他のモジュールをパッケージ化しているかのどちらかだからです.この構成項目は奇妙になります.また、ネット上のものは、バージョンが不明で、バージョン番号が異なり、解決策や構成方法が全く異なる可能性があります.多くの文章では、彼らがどのバージョンを使っているのかは言及されていません.私は頭がくらくらしています(結局、私はこれらのサービスモジュールの開発者や長期的な使用者ではありません.これらのバージョンの進化過程をよく理解していません).
だからここは多くの資料を調べて、テストはいくつかの方案に合格して、自分で総括して記録します
注意!
ここではいずれもEurekaがサービスセンターになることを前提としている
ツール
Feign + Hystrix
この栗のソースはこちら
0.デフォルトの基本構成
最も基本的な構成は、Hystrix独自の長い一連の構成:
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds
ですが、Feignモジュールでは、このタイムアウト時間を単独で設定することはできません.また、Ribbonのタイムアウト時間を追加する必要があります.例えば、次のようにします.hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
ribbon:
ReadTimeout: 5000
ConnectTimeout: 5000
Hystrixの構成については、公式の説明があります.
Default Value
1000
Default Property
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds
Instance Property
hystrix.command.HystrixCommandKey.execution.isolation.thread.timeoutInMilliseconds
How to Set Instance Default
HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(int value)
インスタンス構成でdefaultの代わりにHystrixCommandKeyが表示されます.この値は次のようになります.
1.異なるインスタンスの構成
さらに、タイムアウト時間を異なるサービスインスタンスに細分化することもできます.たとえば、次のようになります.
@FeignClient(
value = "hello-service",
fallback = MyFeignClientHystric.class)
public interface MyFeignClient {
@RequestMapping("/hello")
String sayHelloByFeign();
@RequestMapping("/why")
String sayWhyByFeign();
}
hystrix:
command:
"MyFeignClient#sayWhyByFeign()":
execution:
isolation:
thread:
timeoutInMilliseconds: 9000
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 2000
ribbon:
ReadTimeout: 5000
ConnectTimeout: 5000
この書き方は、デフォルトのタイムアウト時間を2秒に変更し、別のカスタムFeignクライアントのあるメソッドのタイムアウト時間を9秒に設定します(フォーマットは
# ()
で、メソッドにパラメータがあれば、パラメータのタイプもつづります).ここでのMyFeignClient#sayWhyByFeign()
は、上記のcommandKey
を表していますが、この書き方は、Feignモジュールの特殊なものです.ryanjbaxter commented on 26 Jul
If you had a Feign client called MyClient and it had a method called search that took in a single String parameter than you would use the following propertyhystrix.command.MyClient#search(String).execution.isolation.thread.timeoutInMilliseconds
issueのSpring Cloudの公式スタッフによると、このフォーマットは彼らが行ったパッケージなので、設定するには、このように書くしかありません.
Ribbon + Hystrix
この栗のソースはこちら
0.デフォルトの基本構成
Ribbonを使用する場合、Hystrixのタイムアウト時間を設定するだけで有効になります.Ribbonのタイムアウト時間を追加する必要はありません.たとえば、次のようにします.
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 9000
1.異なるインスタンスの構成
サービスタイムアウト時間を細分化したい場合:
同じサービスインスタンスの異なるインタフェースである場合、異なるタイムアウト時間を使用するには、
@HystrixCommand
のcommandKey
を異なる値として定義し、ymlでそれぞれ設定します.@HystrixCommand(
commandKey = "helloService-sayHello",
fallbackMethod = "sayHelloDefault")
public String sayHelloByRibbon() {
return restTemplate.getForObject("http://HELLO-SERVICE/hello", String.class);
}
public String sayHelloDefault() {
return "hello service error, this is default say hello method";
}
@HystrixCommand(
commandKey = "helloService-sayWhy",
fallbackMethod = "sayWhyDefault")
public String sayWhyByRibbon() {
return restTemplate.getForObject("http://HELLO-SERVICE/why", String.class);
}
public String sayWhyDefault() {
return "hello service error, this is default say why method";
}
hystrix:
command:
helloService-sayWhy:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 1500
同じサービスインスタンスの各メソッドのタイムアウト時間を統一的に設定したい場合は、テストにより、異なるメソッドの
commandKey
を同じ値に設定することができ、ymlでキーをタイムアウト構成すると同時に有効になります.@HystrixCommand(
commandKey = "helloService",
fallbackMethod = "sayHelloDefault")
public String sayHelloByRibbon() {
return restTemplate.getForObject("http://HELLO-SERVICE/hello", String.class);
}
public String sayHelloDefault() {
return "hello service error, this is default say hello method";
}
@HystrixCommand(
commandKey = "helloService",
fallbackMethod = "sayWhyDefault")
public String sayWhyByRibbon() {
return restTemplate.getForObject("http://HELLO-SERVICE/why", String.class);
}
public String sayWhyDefault() {
return "hello service error, this is default say why method";
}
hystrix:
command:
helloService:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000
Zuul
この栗のソースコードはここを見て、Zuulの中の降格は
FallbackProvider
を使って、簡単な使用は私のソースコードの中のHelloFallback Providerを見ることができます.JAvaとHiFallbackProvider.JAva、私も公式のドキュメントの説明と例を参考にしました.0.デフォルトの基本構成
zulでタイムアウト時間を設定するには、公式の紹介によると、2つの状況に分けられます.
ribbon.ReadTimeout
とribbon.SocketTimeout
でzuul.host.connect-timeout-millis
とzuul.host.socket-timeout-millis
を用いる私のコードではサービスId方式を使用しているので、最初の構成を参照してください.例えば、
zuul:
routes:
helloService:
path: /hello-service/**
serviceId: hello-service
hiService:
path: /hi-service/**
serviceId: hi-service
ribbon:
ConnectTimeout: 5000
ReadTimeout: 5000
1.異なるインスタンスの構成
Ribbonの構成項目には
ClientName
を接頭辞(この方法の出典は公式のwiki)として追加することもでき、異なるクライアントの下での構成を区別することができます.このClientName
はserviceIdを直接使って、正常をテストしましたが、どの値を使うべきか、これはまだ公式の説明を見つけていません.zuul:
routes:
helloService:
path: /hello-service/**
serviceId: hello-service
hiService:
path: /hi-service/**
serviceId: hi-service
hello-service:
ribbon:
ConnectTimeout: 5000
ReadTimeout: 5000
hi-service:
ribbon:
ConnectTimeout: 500
ReadTimeout: 500
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
また、RibbonとHystrixのタイムアウト時間を同時に構成すると、上記の構成ではhi-serviceのインタフェース呼び出しが0.5秒を超えるとタイムアウトがトリガーされるなど、最小の基準でテストを行った.
まとめ
現在の学習とテストの結果を見ると、
commandKey
を自由に定義してタイムアウト時間の構成commandKey
をカプセル化しているため、カスタマイズできないため、同じFeignClientでのサービスインタフェースの便利な統一構成ができず、対応するビジネスニーズがあれば、特殊なインタフェースごとに独立したタイムアウト構成(新しい方法が見つかれば更新)広告を出す
記事は、個人ブログ『Zuul、Ribbon、Feign、Hystrix使用時のタイムアウト時間設定の問題』に初登場