Spring RestTemplate 시간 초과


125

내 웹 응용 프로그램에서 사용하는 나머지 서비스에 대한 연결 시간 제한을 설정하고 싶습니다. Spring의 RestTemplate을 사용하여 내 서비스와 대화하고 있습니다. 나는 약간의 조사를 해왔고 시간 제한을 설정하기위한 것으로 생각되는 아래 xml (내 응용 프로그램 xml에서)을 찾아서 사용했습니다. 저는 Spring 3.0을 사용하고 있습니다.

또한 RestTemplate을 사용하여 Spring 웹 서비스에 대한 Timeout 구성 에서 동일한 문제를 보았지만 솔루션이 깨끗 하지 않은 것 같습니다. 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.ResourceAccessExcep tion : I / O error : No route to host : connect; 중첩 된 예외는 java.net.NoRouteToHostException : 호스트에 대한 경로 없음 : connect

URL이 잘못되어 나머지 서비스에서 404가 반환 됨 : 약 10 초 동안 대기하고 다음 예외를보고합니다.

org.springframework.web.client.HttpClientErrorException : 404 찾을 수 없음

내 요구 사항에는 더 짧은 시간 제한이 필요하므로이를 변경할 수 있어야합니다. 내가 뭘 잘못하고 있는지에 대한 아이디어가 있습니까?

감사합니다.

답변:


164

들어 봄 부팅> 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공개 세터을 가지고 connectionRequestTimeout, connectTimeout그리고 readTimeout그리고 @ConfigurationProperties당신을 위해 세트를.


들어 봄 부팅없이 스프링 4.1 스프링 (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 on Spring Boot> = 2.1.8에서 구성을 시도했지만 성공하지 못했습니다. 이 게시물 ( zetcode.com/springboot/resttemplate )을 따라 구성을 만들었습니다.
Ângelo Polotto

@ ÂngeloPolotto 귀하가 게시 한 링크는이 솔루션과 동일한 조언을 제공합니다. 이 기사는 "또는 RestTemplateBuilder를 사용하여 작업을 수행 할 수 있습니다."라고 말합니다.
dustin.schultz

76

나는 마침내 이것을 작동시켰다.

우리 프로젝트에 commons-httpclient jar의 두 가지 버전이 있다는 사실이 도움이되지 않았다고 생각합니다. 내가 그것을 분류하면 두 가지를 할 수 있다는 것을 알았습니다.

코드에서 다음을 넣을 수 있습니다.

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

이 코드를 처음 호출하면 .NET Framework에서 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 call 10 초, get call 5 초 등)
codesalsa

@ 사르도. 내 코드에서 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
comiventor

40

이 질문은 Spring Boot 검색에 대한 첫 번째 링크이므로 공식 문서에서 권장 하는 솔루션을 여기에 넣으면 좋습니다 . Spring Boot에는 자체 편의 빈 RestTemplateBuilder가 있습니다 .

@Bean
public RestTemplate restTemplate(
        RestTemplateBuilder restTemplateBuilder) {

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

RestTemplate 인스턴스의 수동 생성은 다른 자동 구성 빈이 수동으로 생성 된 인스턴스에 주입되지 않기 때문에 잠재적으로 문제가 될 수 있습니다.


2
저와 같은 Spring 신참을위한 메모 : @Configuration에 이것을 붙이는 것만으로는 아무것도 할 수 없습니다. 이 메서드를 사용하려면이 RestTemplate을 RestTemplateXhrTransport의 생성자에 대한 인수로 사용하는 위치에 삽입해야합니다.이 RestTemplate은 SocksJSClient에 전달하는 전송 목록에 차례로 추가합니다.
Key Lay

setConnectTimeout일부 구현의 setReadTimeout사용되지 않습니다
skryvets은

17

여기 내 2 센트입니다. 새로운 것은 없지만 일부 설명, 개선 및 최신 코드.

기본적으로 RestTemplate시간 제한이 무제한입니다. 시간 초과에는 연결 시간 초과와 읽기 시간 초과의 두 가지 종류가 있습니다. 예를 들어, 서버에 연결할 수 있지만 데이터를 읽을 수 없습니다. 응용 프로그램이 중단되었고 무슨 일이 일어나고 있는지 전혀 알 수 없습니다.

요즘에는 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();
    }
}

두 번째 솔루션에서는 RestTemplateBuilder. 또한 두 가지 방법의 매개 변수에 유의하십시오 Duration. 밀리 초가 직접 걸리는 오버로드 된 메서드는 이제 더 이상 사용되지 않습니다.

Spring Boot 2.1.0 및 Java 11로 테스트 한 편집 .


어떤 봄과 자바 버전을 사용하고 있습니까?
orirab

2
Spring Boot 2.1.0 및 Java 11. 작동하는 예제를 보려면 내 튜토리얼을 살펴볼 수 있습니다. zetcode.com/springboot/resttemplate
Jan Bodnar

나는 대답이 추가 제안
orirab

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

benscabbia의 답변 을 확장하려면 다음을 수행하십시오.

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는 시간 제한을 설정하는 데 도움이되지만 기능이 매우 제한되어 실시간 응용 프로그램에서 충분하지 않을 수 있습니다. 프로덕션 코드에서는 resttemplate과 함께 HTTP 클라이언트 라이브러리를 지원하는 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.