Spring Boot RestTemplate 随机 ResourceAccessException: 连接重置错误

5

我有一个实现了4个微服务的系统。这四个服务需要偶尔共享信息,它们通过使用Spring的RestTemplate进行RESTful请求来实现。目前,大约5%-10%的请求会失败,并出现如下异常:

org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://otherservice.com/path": Connection reset; nested exception is java.net.SocketException: Connection reset

再次出现这种情况似乎是随机的,只有5%-10%的几率会出错。我已经尝试了多种方法,但没有什么效果。目前,我正在尝试以下方法:

配置:

@Configuration
public class BeanConfiguration {

    @Bean
    public RestTemplate restTemplate() {
        ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(HttpClients.createDefault());
        return new RestTemplate(requestFactory);
    }
}

服务:

@Autowired
public MyService(RestTemplate restTemplate) {
    this.restTemplate = restTemplate;
}

public Contact addContact(Contact contact) {
    HttpEntity<Contact> entity = new HttpEntity<>(contact, authenticationTokenInfo.setTokenHeaders());
    ResponseEntity<Contact> response = restTemplate.exchange(contact_base_url, HttpMethod.POST, entity, Contact.class);
    return response.getBody();
}

我尝试了许多不同的方法,但都没有任何效果。比如说,我尝试了以下方法:

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
    return builder.build();
}

我正在记录每个微服务的所有请求,但似乎这些请求实际上没有到达其他服务。它们只是失败了。根据日志,它们在不到50毫秒的时间内失败,因此这不是超时问题。对于其中的一些,我已经实现了指数级退避重试,但这并不是一个可行的解决方案。


2
老实说,我放弃尝试修复它了。我不再注入rest模板,只有在需要时才创建一个新的。我尝试了一百种不同的方法,包括创建rest模板连接池,但没有其他方法可行。 - Gremash
1
我在使用Salesforce REST API时遇到了相同的问题。有什么解决方法吗? - Nix
有人对这个问题有新的信息吗?我正在尝试@Gremash的解决方案,每当我需要时创建一个新的RestTemplate。到目前为止,它似乎是有效的。 - John Thompson
不知道是否有人已经找到了解决方案,我也遇到了与@Nix一样的问题,无法访问Salesforce REST API。但是我发现了这个帖子,它似乎通过重试来解决症状,至少我看不到它解决了实际问题,尽管我不再收到实际的ResourceAccessException,但在调用重试时可能会发生某些异常。 - Yantes
我至少可以看到重试的原因是“连接重置”异常,这通常会导致我遇到ResourceAccessException。 - Yantes
显示剩余3条评论
1个回答

0

我也遇到了同样的问题。看起来问题出在连接池中的空闲连接上。 这在我的情况下解决了问题,不再偶尔出现任何错误。

     HttpClient httpClient = HttpClients
                .custom()
                .evictIdleConnections(60000, TimeUnit.MILLISECONDS)
                .build();

    HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接