2016-01-18 39 views
6

リクエストの一部としてサードパーティのサービスを呼び出すことがあるSpring Boot RESTサービスがあります。すべてのリソース(5秒と言う)にタイムアウトを設定したいので、リクエスト処理(チェーン全体、応答から応答まで)が5秒以上かかると、コントローラーは実際の応答ではなくHTTP 503で応答します。これはSpring Boot REST API - リクエストタイムアウト?

spring.mvc.async.request-timeout=5000 

を設定する例えば、ちょうど春の財産だった場合、それは素晴らしいだろうが、私はそれですべての運を持っていませんでした。また、WebMvcConfigurationSupportを拡張し、configureAsyncSupportをオーバーライドしてみました。

@Override 
public void configureAsyncSupport(final AsyncSupportConfigurer configurer) { 
    configurer.setDefaultTimeout(5000); 
    configurer.registerCallableInterceptors(timeoutInterceptor()); 
} 

@Bean 
public TimeoutCallableProcessingInterceptor timeoutInterceptor() { 
    return new TimeoutCallableProcessingInterceptor(); 
} 

私はサードパーティのすべてのコールを手動でタイムアウトする必要があり、時間がかかり過ぎるとタイムアウト例外をスローすることが考えられます。そうですか?または、すべてのリクエストエンドポイントをカバーする、より簡単で総合的なソリューションがありますか?

答えて

9

を使用する必要がありますよりも、あなたはspring.mvc.async.request-timeout=5000がしたい場合は、Callabeを返す必要があります作業。

@RequestMapping(method = RequestMethod.GET) 
public Callable<String> getFoobar() throws InterruptedException { 
    return new Callable<String>() { 
     @Override 
     public String call() throws Exception { 
      Thread.sleep(8000); //this will cause a timeout 
      return "foobar"; 
     } 
    }; 
} 
+3

のJava 8を使用している場合は、また、ラムダ式を使用することができます。 'return() - > {/ *あなたのものをここで* /}'; – demaniak

2

あなたはRestTemplateを使用している場合は、次のコードのタイムアウトを実装する

@Bean 
public RestTemplate restTemplate() { 
    return new RestTemplate(clientHttpRequestFactory()); 
} 

private ClientHttpRequestFactory clientHttpRequestFactory() { 
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); 
    factory.setReadTimeout(2000); 
    factory.setConnectTimeout(2000); 
    return factory; 
}} 

xml構成

<bean class="org.springframework.web.client.RestTemplate"> 
<constructor-arg> 
    <bean class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory" 
     p:readTimeout="2000" 
     p:connectTimeout="2000" /> 
</constructor-arg> 

1

信頼できない/遅いリモート呼び出しを処理するために、Spring Cloud Netflix Hystrixスターターを検討することをお勧めします。それは正確にこのようなもののために意図されているサーキットブレーカパターンを実装しています。

offcial docs for more informationを参照してください。

+1

私はこれがなぜ落とされたのか分かりませんが、回路ブレーカーのパターンを実装するのが最善の答えです。それ以外の場合は、要求を実行したままで503を返すだけで、おそらくリソースが浪費されます – Jeremie

0

application.propertiesにserver.connection-timeout=5000を試すことができます。コネクタは 接続を閉じる前に、別のHTTPリクエストを待ちます(ミリ秒単位)

server.connectionタイムアウト=#時間:official documentationから。 が設定されていない場合は、コンテナ固有のデフォルトが使用されます。無限(つまり無限)のタイムアウトを示すには、 の値を-1にします。

一方、あなたは私はすでにここに私の答えで説明したようにサーキットブレーカーパターンを使用して、クライアント側のタイムアウトを処理することもできますが:https://stackoverflow.com/a/44484579/2328781

関連する問題