JavaのRestTemplateでタイムアウトを設定する方法

こんにちは。 エキサイト株式会社の三浦です。

APIにアクセスする際、一定時間までにレスポンスが返ってこなかったらエラーとして処理したい、というのはよくある要望かと思います。 そのために使用するタイムアウト設定について、JavaのRestTemplateで設定する方法を説明します。

タイムアウト

APIなどにネットワーク経由でアクセスする場合、必ずしもレスポンスがすぐに返ってくるとは限りません。 API自体に不具合があったり、アクセスが急増していたり、ネットワークに問題があったりなど、様々な理由でレスポンスが返ってくるまでに時間がかかってしまう可能性があります。

バッチなど、多少時間がかかっても問題がないアプリケーションであれば大丈夫かもしれませんが、Webページ用のサーバであればそうも言っていられないこともあるでしょう。 そのような場合、「指定した一定時間でレスポンスが返ってこなかったらエラーとして処理する」というタイムアウト設定をするのが一般的です。

RestTemplateにおけるタイムアウト設定

RestTemplateでは、以下のようにすればタイムアウト設定ができます。

build.gradle

// バージョンは適宜変更してください
implementation 'org.apache.httpcomponents:httpclient:4.5.13'

タイムアウト設定

import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;

@Configuration
public class RestConfig {

    @Bean
    public RestTemplate restTemplate() {
        var clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(HttpClientBuilder.create().build());

        // ここでタイムアウトを設定

        // 接続が確立するまでのタイムアウト
        clientHttpRequestFactory.setConnectTimeout(500);

        // コネクションマネージャーからの接続要求のタイムアウト
        clientHttpRequestFactory.setConnectionRequestTimeout(500);

        // ソケットのタイムアウト(パケット間のタイムアウト)
        clientHttpRequestFactory.setReadTimeout(1000);

        return new RestTemplate(clientHttpRequestFactory);
    }
}

終わりに

タイムアウトを設定していないと、思わぬところでWebページの応答速度が大きくなってしまう可能性があります。 Webページの要件ごとにタイムアウト時間は異なってくると思うので、適切な設定をしましょう。