2014-02-21 3 views
7

я установка RestTemplate и AsyncRestTemplate в моем проекте, подобное следующему:Как установить тайм-аут на AsyncRestTemplate от Spring?

http://vincentdevillers.blogspot.fr/2013/10/a-best-spring-asyncresttemplate.html

Я заметил, что таймаут соединения фактически не работает, если я не изменить httpRequestFactory() фасоли в быть следующими:

@Bean 
public ClientHttpRequestFactory httpRequestFactory() { 
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient()); 
    factory.setConnectTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS); 
    factory.setReadTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS); 
    return factory; 
} 

Если установить DEFAULT_READ_TIMEOUT_MILLISECONDS до 5, тайм-аут происходит, когда я использую restTemplate (как ожидалось). Однако, когда я использую AsyncRestTemplate, тайм-аут не возникает. Я изменил asyncHttpRequestFactory(), как httpRequestFactory(), но не кубик.

@Bean 
public AsyncClientHttpRequestFactory asyncHttpRequestFactory() { 
    HttpComponentsAsyncClientHttpRequestFactory factory = new HttpComponentsAsyncClientHttpRequestFactory(asyncHttpClient()); 
    factory.setConnectTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS); 
    factory.setReadTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS); 
    return factory; 
} 

Вот как я пытаюсь использовать AsyncRestTemplate в MVC контроллер Spring:

String url = "..."; 
// Start the clock 
long start = System.currentTimeMillis(); 

ListenableFuture<ResponseEntity<String>> results = asyncRestTemplate.getForEntity(url, String.class); 
// Wait until the request is finished 
while (!(results.isDone())) { 
    Thread.sleep(10); //millisecond pause between each check 
} 
System.out.println("Elapsed time: " + (System.currentTimeMillis() - start)); 
return results.get().getBody(); 

Как я могу получить AsyncRestTemplate читать мои настройки тайм-аута соединения?

В соответствующей заметке https://spring.io/guides/gs/async-method/ использует @Async и RestTemplate и, похоже, выполняет то, что я ищу. В чем преимущество использования AsyncRestTemplate над RestTemplate?

+0

Глядя на источник, 'HttpComponentsAsyncClientHttpRequestFactory' игнорирует свойства' connectTimeout' и 'readTimeout'. Я не знаю, почему. –

ответ

3

Я думаю, что точка AsyncRestTemplate - это ListenableFuture (функции которой вы действительно не используете). Так что, вероятно, @Async подходит для вашего случая использования. Кроме того, я думаю, что results.get(5,TimeUnit.SECOND) более эффективен (и изящно), а затем цикл с Thread.sleep(...), но это зависит от вас, я думаю. Или, может быть, я что-то упустил.

+0

У меня также есть аналогичный вопрос [здесь] (http: // stackoverflow.com/questions/29380653/how-to-correct-cancel-the-http-request-if-they-are-take-too-much-time), который использует «AsyncRestTemplate» вместе с его «ListenableFuture», и у меня мало сомнений по моей проблеме, которую я пытаюсь выполнить. Если возможно, вы можете помочь мне там, когда у вас появится шанс. Любая помощь действительно ценится. – john

+0

Я думаю, что это опечатка. Это должно быть 'results.get (5, TimeUnit.SECONDS)' вместо 'results.get (5, TimeUnit.SECOND)' – simomo

3

AsyncRestTemplate полагается на возможности NIO-клиента HTTP, поэтому вы можете управлять большим количеством подключений с небольшим количеством потоков. Для достижения аналогичного результата с @Async + RestTemplate потребуется гораздо больше ресурсов. Если вы делаете это только в нескольких местах, то это, вероятно, хорошо, хотя даже тогда AsyncRestTemplate, поскольку он существует, немного лучше и более специализирован для использования.

Что касается таймаута чтения, похоже, что это может быть недосмотр. Не стесняйтесь создавать билет. Быстрый взгляд на this page, пример конфигурации «HttpAsyncClient», показывает:

IOReactorConfig.custom().setConnectTimeout(30000).

Я полагаю, вы могли бы дать, что быстро попробовать

+0

У меня также есть аналогичный вопрос [здесь] (http://stackoverflow.com/questions/29380653/how-to-correct-cancel-the-http-request-if-they-are-take-too-much-time), который использует «AsyncRestTemplate» вместе с его «ListenableFuture», и у меня мало сомнений в моей проблеме, что я я пытаюсь выполнить. Если возможно, вы можете помочь мне там. Я считаю, что «AsyncRestTemplate» довольно крут, так как он использует соединения на основе NIO. – john

0
public CloseableHttpAsyncClient asyncHttpClient() { 
    IOReactorConfig ioReactorConfig = IOReactorConfig.custom().setConnectTimeout(getProperties().getConnectTimeout()).setSoTimeout(getProperties().getReadTimeout()).build() 
    return HttpAsyncClients.custom().setDefaultIOReactorConfig(ioReactorConfig).build(); 
} 

как это, AsyncRestTemplate таймаут конфигурировать нормально.

3

Очень похоже на sync один:

final SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); 
requestFactory.setTaskExecutor(new SimpleAsyncTaskExecutor()); 
requestFactory.setConnectTimeout(connectTimeout); 
requestFactory.setReadTimeout(readTimeout); 

final AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate(); 
asyncRestTemplate.setAsyncRequestFactory(requestFactory); 

С source code, вы можете увидеть, что AsyncRestTemplate экземпляр создается с помощью SimpleClientHttpRequestFactory вместе с SimpleAsyncTaskExecutor. Таким образом, вы можете просто сделать то же самое с помощью экземпляра SimpleClientHttpRequestFactory, значения тайм-аута которого установлены.

+0

Может использовать некоторые изменения, чтобы лучше объяснить, как это отвечает на вопрос. – paisanco