首先,需要确认在设置MaxAutoRetries时,是否特别考虑了请求重定向的情况。如果不是,那么重定向也会被视为一次请求,进而导致请求次数超过预设的MaxAutoRetries值。
其次,还需要检查请求是否在不同的服务实例之间反复轮换。如果是,那么MaxAutoRetries也会被重复计数并被迅速耗尽。
下面是一份相关代码示例,其中包括对请求重定向和服务实例轮换的特殊处理。
@Configuration
public class RibbonConfiguration {
@Bean
@ConditionalOnMissingBean
public IRule ribbonRule() {
return new WeightedResponseTimeRule();
}
@Bean
public IPing ribbonPing() {
return new PingUrl();
}
@Bean
public ServerListSubsetFilter serverListFilter() {
ServerListSubsetFilter filter = new ServerListSubsetFilter();
filter.setRetries(3); // 指定每个服务实例最多被重试 3 次
filter.setIncludeHosts(HostFromConfig.getHosts()); // 设置要包含的服务主机列表
return filter;
}
@Bean
@Primary
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public RetryableRibbonLoadBalancingHttpClient ribbonHttpClient(
IClientConfig config,
ILoadBalancer loadBalancer,
RetryHandler retryHandler) {
return new RetryableRibbonLoadBalancingHttpClient(
config,
new HttpClientOptions(loadBalancer),
retryHandler) {
@Override
public ClientHttpResponse execute(
final HttpRequest request,
final byte[] body,
final ClientHttpRequestExecution execution) throws IOException {
/*
* 如果当前请求已经达到了最大重试次数,直接返回异常来终止请求。
*/
if (alreadyRetriedOrMaxRetriesReached(extractRetryable(request), config, loadBalancer)) {
throw new RuntimeException("Maximum retries reached.");
}
return super.execute(request, body, execution);
}
@Override
protected HttpRequest applyRetryHeaders(
IClientConfig overriddenClientConfig,
HttpRequest request,
RibbonHttpResponse httpResponse,
Collection<String> retryableStatusCodes) {
/*
* 如果发现请求被重定向,那么重试也需要使用新的重定向地址