155

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 エラー: ホストへのルートがありません: connect; ネストされた例外は java.net.NoRouteToHostException: No route to host: connect です

URL が正しくないため、残りのサービスから 404 が返されました: 約 10 秒待機し、次の例外を報告します:

org.springframework.web.client.HttpClientErrorException: 404 が見つかりません

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

どうもありがとう。

4

9 に答える 9

79

私はついにこれを機能させました。

私たちのプロジェクトに 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し、プロパティ ファイルからタイムアウト値を取得します。

于 2013-02-26T15:32:51.680 に答える
27

これが私の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 でテスト済み。

于 2018-11-27T12:16:24.737 に答える
0
private static RestTemplate restTemplate;

static {
    HttpComponentsClientHttpRequestFactory rf = new HttpComponentsClientHttpRequestFactory();
    rf.setReadTimeout(3 * 1000);
    rf.setConnectTimeout(2 * 1000);

    restTemplate = new RestTemplate(rf);
    restTemplate.getMessageConverters()
        .add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));
}
于 2021-11-05T03:28:08.740 に答える