Spring RestTemplateタイムアウト


125

Webアプリケーションで使用されるRESTサービスの接続タイムアウトを設定したいのですが。SpringのRestTemplateを使用してサービスと通信しています。私はいくつかの調査を行い、以下のxmlを見つけて使用しました(私のアプリケーションxml内)。これは、タイムアウトを設定するためのものです。Spring 3.0を使用しています。

RestTemplateを使用したSpring Webサービスのタイムアウト構成でも同じ問題が発生しましたが、ソリューションはそれほどきれいではないようです。Spring構成を介してタイムアウト値を設定することをお勧めします

<bean id="RestOperations" class="org.springframework.web.client.RestTemplate">
    <constructor-arg>

      <bean class="org.springframework.http.client.CommonsClientHttpRequestFactory">
        <property name="readTimeout" value="${restURL.connectionTimeout}" />
      </bean>
    </constructor-arg>
</bean>

readTimeoutを何に設定しても、次のようになります:

ネットワークケーブルが切断されました: 約20秒待機し、次の例外を報告します:

org.springframework.web.client.ResourceAccessException:I / Oエラー:ホストへのルートがありません:接続。ネストされた例外はjava.net.NoRouteToHostException:ホストへのルートがありません:接続

URLが正しくないため、404がRESTサービスによって返されました: 約10秒間待機し、次の例外を報告します:

org.springframework.web.client.HttpClientErrorException:404 Not Found

私の要件では、タイムアウトを短くする必要があるため、これらを変更できるようにする必要があります。私が間違っていることについてのアイデアはありますか?

どうもありがとう。

回答:


163

以下のための春ブーツ> = 1.4

@Configuration
public class AppConfig
{
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) 
    {
        return restTemplateBuilder
           .setConnectTimeout(...)
           .setReadTimeout(...)
           .build();
    }
}

以下のための春ブーツ<= 1.3

@Configuration
public class AppConfig
{
    @Bean
    @ConfigurationProperties(prefix = "custom.rest.connection")
    public HttpComponentsClientHttpRequestFactory customHttpRequestFactory() 
    {
        return new HttpComponentsClientHttpRequestFactory();
    }

    @Bean
    public RestTemplate customRestTemplate()
    {
        return new RestTemplate(customHttpRequestFactory());
    }
}

その後で application.properties

custom.rest.connection.connection-request-timeout=...
custom.rest.connection.connect-timeout=...
custom.rest.connection.read-timeout=...

ので、これは動作しますHttpComponentsClientHttpRequestFactory公共のセッターを持っているconnectionRequestTimeoutconnectTimeoutと、readTimeoutそして@ConfigurationPropertiesあなたのためにそれらを設定します。


以下のために春ブーツなしの春4.1やSpring 5使用して@Configurationの代わりにXML

@Configuration
public class AppConfig
{
    @Bean
    public RestTemplate customRestTemplate()
    {
        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        httpRequestFactory.setConnectionRequestTimeout(...);
        httpRequestFactory.setConnectTimeout(...);
        httpRequestFactory.setReadTimeout(...);

        return new RestTemplate(httpRequestFactory);
    }
}

いい例です!例では、奇妙なnewステートメントを削除してくださいSpring Boot
StasKolodyuk

7
この構成の後、RestTemplateはapache httpクライアントを使用することに注意してください(タイムアウトを設定するため)。Apache httpクライアント接続プールのデフォルトのmaxPerRouteスレッドは5、最大合計スレッドは10(httpClient-4.5.2)です。状況によっては、これを自分で設定する必要があります(多くのホストに接続し、さらに多くの接続が必要な場合など)。
bluearrow

2
メモしてくださいconnectionRequestTimeout属性は4.1.4.RELEASE前に利用可能ではありません
Taoufik Mohdit

Spring Boot> = 1.4でSpring Boot> = 2.1.8の構成を試しましたが、うまくいきませんでした。この投稿(zetcode.com/springboot/resttemplateに従って、その構成を行いました。
アンジェロPolotto

@ÂngeloPolotto投稿したリンクは、このソリューションと同じアドバイスを提供します。この記事では、「代わりに、RestTemplateBuilderを使用して作業を行うことができます。」と述べています。
dustin.schultz

76

ようやくこれが機能しました。

私たちのプロジェクトにcommons-httpclient jarの2つの異なるバージョンがあったという事実は役に立たなかったと思います。それを整理したら、2つのことができることがわかりました...

コードでは、次のように記述できます。

HttpComponentsClientHttpRequestFactory rf =
    (HttpComponentsClientHttpRequestFactory) restTemplate.getRequestFactory();
rf.setReadTimeout(1 * 1000);
rf.setConnectTimeout(1 * 1000);

このコードが初めて呼び出されたときに、がHttpComponentsClientHttpRequestFactory使用するクラスのタイムアウトを設定しRestTemplateます。したがって、によって行われる後続のすべての呼び出しは、RestTemplate上で定義されたタイムアウト設定を使用します。

または、これを行うことをお勧めします:

<bean id="RestOperations" class="org.springframework.web.client.RestTemplate">
    <constructor-arg>
        <bean class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
            <property name="readTimeout" value="${application.urlReadTimeout}" />
            <property name="connectTimeout" value="${application.urlConnectionTimeout}" />
        </bean>
    </constructor-arg>
</bean>

RestOperationsコードでインターフェイスを使用し、プロパティファイルからタイムアウト値を取得する場所。


そのため、これはこのレストテンプレート(シングルトン)を介したすべての呼び出しのタイムアウトを設定します。リクエストごとのタイムアウトを制御できるかどうか知っていますか?(例:postコールの場合は10秒、getコールの場合は5秒)
codessa

@ sardo。コードでRestOperationsインターフェイスを使用する場所。このために明示的なインターフェイスを作成する必要がありますか?
デッドエンド

Spring 3.0を使用しているとおっしゃっていましたが、これも行き詰まっていますが、3.0にはHttpComponentsClientHttpRequestFactoryがありません。Springを更新しましたか?
Kutzi

5
上記のコードは最新のSpringでは動作しません。ClassCastExceptionが発生しますjava.lang.ClassCastException: org.springframework.http.client.InterceptingClientHttpRequestFactory cannot be cast to org.springframework.http.client.HttpComponentsClientHttpRequestFactory
コミベーター2018

40

この質問は、Spring Boot検索の最初のリンクです。したがって、公式ドキュメントで推奨されているソリューションをここに置くとよいでしょう。Spring Bootには独自の便利なBean RestTemplateBuilderがあります。

@Bean
public RestTemplate restTemplate(
        RestTemplateBuilder restTemplateBuilder) {

    return restTemplateBuilder
            .setConnectTimeout(Duration.ofSeconds(500))
            .setReadTimeout(Duration.ofSeconds(500))
            .build();
}

RestTemplateインスタンスを手動で作成することは、他の自動構成されたBeanが手動で作成されたインスタンスに注入されないため、潜在的に厄介なアプローチです。


2
私のようなSpringの初心者へのメモ:これを@Configurationに貼り付けても何も起こりません。このメソッドでは、RestTemplateXhrTransportのコンストラクターへの引数としてそれを使用する、このRestTemplateがsomに挿入されている必要があります。これは、SocksJSClientに渡すトランスポートのリストに追加されます。
キーレイ

setConnectTimeoutおよびの一部の実装setReadTimeoutは非推奨
skryvets

17

これが私の2セントです。何も新しいものではありませんが、いくつかの説明、改善、新しいコードがあります。

デフォルトでは、 RestTemplateはタイムアウトは無限です。タイムアウトには、接続タイムアウトと読み取りタイムアウトの2種類があります。たとえば、サーバーに接続できましたが、データを読み取ることができませんでした。アプリケーションがハングしていて、何が起こっているのかわかりません。

私はアノテーションを使用するつもりですが、最近ではXMLよりも好まれています。

@Configuration
public class AppConfig {

    @Bean
    public RestTemplate restTemplate() {

        var factory = new SimpleClientHttpRequestFactory();

        factory.setConnectTimeout(3000);
        factory.setReadTimeout(3000);

        return new RestTemplate(factory);
    }
}

ここではSimpleClientHttpRequestFactory、接続の設定とタイムアウトの読み取りに使用します。次に、のコンストラクタに渡されRestTemplateます。

@Configuration
public class AppConfig {

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {

        return builder
                .setConnectTimeout(Duration.ofMillis(3000))
                .setReadTimeout(Duration.ofMillis(3000))
                .build();
    }
}

2番目のソリューションでは、を使用しRestTemplateBuilderます。また、2つのメソッドのパラメータにも注目してくださいDuration。直接ミリ秒かかるオーバーロードされたメソッドは廃止されました。

Spring Boot 2.1.0およびJava 11でテスト済みの編集


どの春とJavaのバージョンを使用していますか?
orirab 2018

2
Spring Boot 2.1.0およびJava 11.実際の例については、私のチュートリアルをご覧
Jan Bodnar

これを回答に追加することをお勧めします
orirab 2018

github.com/spring-projects/spring-boot/blob/master/…を参照してください。Spring Boot 2.1.0で追加されました。
Jan Bodnar

あなた@JanBodnarをありがとう、あなたのチュートリアルは私の春ブーツ5.xの上でうまく働いたことである
アンジェロPolotto

15

タイムアウトを設定する本当に簡単な方法を次に示します。

RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());

private ClientHttpRequestFactory getClientHttpRequestFactory() {
    int timeout = 5000;
    HttpComponentsClientHttpRequestFactory clientHttpRequestFactory =
      new HttpComponentsClientHttpRequestFactory();
    clientHttpRequestFactory.setConnectTimeout(timeout);
    return clientHttpRequestFactory;
}

0

同様のシナリオがありましたが、プロキシの設定も必要でした。これを行うために私が見ることができる最も簡単な方法はSimpleClientHttpRequestFactory、プロキシを設定するのが簡単になるようにを拡張することでした(非製品と製品の異なるプロキシ)。これは、プロキシが不要な場合でも機能します。次に、拡張クラスで、openConnection(URL url, Proxy proxy)メソッドをオーバーライドします。 source戻る前にタイムアウトを設定するだけです。

@Override
protected HttpURLConnection openConnection(URL url, Proxy proxy) throws IOException {
    URLConnection urlConnection = proxy != null ? url.openConnection(proxy) : url.openConnection();
    Assert.isInstanceOf(HttpURLConnection.class, urlConnection);
    urlConnection.setConnectTimeout(5000);
    urlConnection.setReadTimeout(5000);
    return (HttpURLConnection) urlConnection;
}

0

ベンスカビアの答えを拡張するには:

private RestTemplate restCaller = new RestTemplate(getClientHttpRequestFactory());

private ClientHttpRequestFactory getClientHttpRequestFactory() {
    int connectionTimeout = 5000; // milliseconds
    int socketTimeout = 10000; // milliseconds
    RequestConfig config = RequestConfig.custom()
      .setConnectTimeout(connectionTimeout)
      .setConnectionRequestTimeout(connectionTimeout)
      .setSocketTimeout(socketTimeout)
      .build();
    CloseableHttpClient client = HttpClientBuilder
      .create()
      .setDefaultRequestConfig(config)
      .build();
    return new HttpComponentsClientHttpRequestFactory(client);
}

0
  1. SimpleClientHttpRequestFactoryを使用したRestTemplateタイムアウトプログラムでタイムアウトプロパティをオーバーライドするには、SimpleClientHttpRequestFactoryクラスを以下のようにカスタマイズします。

SimpleClientHttpRequestFactoryでタイムアウトをオーバーライドする

//Create resttemplate
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());

//Override timeouts in request factory
private SimpleClientHttpRequestFactory getClientHttpRequestFactory() 
{
    SimpleClientHttpRequestFactory clientHttpRequestFactory
                      = new SimpleClientHttpRequestFactory();
    //Connect timeout
    clientHttpRequestFactory.setConnectTimeout(10_000);

    //Read timeout
    clientHttpRequestFactory.setReadTimeout(10_000);
    return clientHttpRequestFactory;
}
  1. HttpComponentsClientHttpRequestFactoryを使用したRestTemplateタイムアウトSimpleClientHttpRequestFactoryはタイムアウトの設定に役立ちますが、機能が非常に制限されており、リアルタイムアプリケーションでは十分でない場合があります。本番用コードでは、HTTPクライアントライブラリとRESTテンプレートをサポートするHttpComponentsClientHttpRequestFactoryを使用することができます。

HTTPClientは、接続プール、アイドル接続管理などの他の便利な機能を提供します。

続きを読む:Spring RestTemplate + HttpClient構成例

HttpComponentsClientHttpRequestFactoryでタイムアウトをオーバーライドする

//Create resttemplate
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());

//Override timeouts in request factory
private SimpleClientHttpRequestFactory getClientHttpRequestFactory() 
{
    HttpComponentsClientHttpRequestFactory clientHttpRequestFactory
                      = new HttpComponentsClientHttpRequestFactory();
    //Connect timeout
    clientHttpRequestFactory.setConnectTimeout(10_000);

    //Read timeout
    clientHttpRequestFactory.setReadTimeout(10_000);
    return clientHttpRequestFactory;
}

参照:Spring RestTemplateタイムアウト構成例

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.