我遇到了一个问题,即应用程序在使用Spring Boot的RestTemplate
进行的后期调用中无限期地阻塞。
ResponseEntity<String> response = restTemplate.postForEntity(destination.getUri(), request, String.class);
我们使用默认的标准JDK实现,并按以下方式创建它:
this.restTemplate = restTemplateBuilder
.setConnectTimeout(5000)
.setReadTimeout(5000)
.build();
将连接和读取超时设置为5秒。但这似乎不是一个绝对值,一旦我们的应用程序收到一些字节,此读取超时就会重置,这将导致我们的应用程序无限期地等待。
我宁愿有一个绝对的读取超时,如果您在不到5秒钟的时间内没有收到最终响应,则模板会抛出TimeoutException
。
我在默认客户端的选项中找不到类似的内容吗?
---编辑---
我尝试了@Peekay答案,但似乎不起作用:
CloseableHttpClient httpClient = HttpClientBuilder.create()
.setConnectionTimeToLive(1, TimeUnit.SECONDS)
.setConnectionManager(new PoolingHttpClientConnectionManager())
.build();
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
clientHttpRequestFactory.setHttpClient(httpClient);
return new RestTemplate(clientHttpRequestFactory);
我还尝试了客户端RestTemplate
的不同实现,例如HttpComponentsClientHttp
,Netty4Client
和OkHttp3Client
像这样创建它们:
Netty4ClientHttpRequestFactory factory = new Netty4ClientHttpRequestFactory();
factory.setConnectTimeout(timeout);
factory.setReadTimeout(readTimeout);
return new RestTemplate(factory);
并在响应时间超过5秒的情况下对其进行了测试。除了Netty返回ReadTimeoutException
以外,所有其他人都返回了200成功。不幸的是,我无法切换到该客户端,如果您想继续使用默认客户端,则似乎需要自己实现。
答案 0 :(得分:1)
是的,您不能设置绝对值,而必须中断胎面本身。
答案 1 :(得分:1)
meow.setOnClickListener((view) ->{
Random random = new Random();
int r = random.nextInt(6-1) + 1;
Toast.makeText(MainActivity.this,Integer.valueOf(r).toString(),Toast.LENGTH_SHORT).show();
try{
if(r==1)
fileDescriptor = MainActivity.this.getResources().openRawResourceFd(R.raw.meowcat1);
else if (r==2)
fileDescriptor = MainActivity.this.getResources().openRawResourceFd(R.raw.meowcat2);
else if (r==3)
fileDescriptor = MainActivity.this.getResources().openRawResourceFd(R.raw.meowcat3);
else if (r==4)
fileDescriptor = MainActivity.this.getResources().openRawResourceFd(R.raw.meowcat4);
else
fileDescriptor = MainActivity.this.getResources().openRawResourceFd(R.raw.meowcat5);
mp.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(), fileDescriptor.getLength());
mp.prepare();
mp.start();
}catch(Exception e){e.printStackTrace();}
});
https://howtodoinjava.com/spring-boot2/resttemplate/resttemplate-timeout-example/
答案 2 :(得分:0)
您可以将其他http客户端与RestTemplate一起使用,例如Apache HttpClient,它可以使您更好地控制如何设置,池化和维护连接:
listprice = browser.find_element_by_xpath("//span[@class='title price']")
price = listprice.text
print(price)
中,您可以设置连接生存时间,即连接的最大TTL。AttributeError: 'NoneType' object has no attribute 'text'
来指定一个连接超时(等待建立连接的最长时间)和一个单独的 socket超时(最大时间) read()将等待数据。)有关更多详细信息,请参见:setConnectTimeout vs. setConnectionTimeToLive vs. setSocketTimeout()
答案 3 :(得分:0)
我们解决此问题的方法是将RestTemplate
REST调用包装在CompletableFuture
中,并使用包装器中的超时功能杀死线程,如果它花费的时间太长。
这里是一个例子:
CompletableFuture<T> requestWrapper = CompletableFuture.supplyAsync(() -> {
return restTemplate.postForEntity(/* Whatever arguments you need to pass */);
});
try {
return requestWrapper.get(5000, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
requestWrapper.cancel(true);
throw new TimeoutException("Endpoint took too long to respond, TimeoutException is triggered");
} catch (ExecutionException e) {
throw e.getCause();
}