核心思想:
对于ConnectTimeout与ReadTimeout这两个配置,底层代码似乎有bug,代码发现并没有对超时处理进行生效,所以我建议使用RestTemplate原始配置即可。 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds:断路器的超时时间需要大于ribbon的超时时间,不然不会触发重试。(对于D版本及以前有效)
配置:yml文件
#retry重试策略:true开启
spring.cloud.loadbalancer.retry.enabled=true
##在E版本以后 对于Ribbon的重试 就不需要设置断路器超时时间了
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000
custom.requestFactory.connect-timeout=10000
custom.requestFactory.connection-request-timeout=10000
custom.requestFactory.read-timeout=2000
##针对于某一个微服务进行重试策略配置: customer-service为服务
##对所有的请求都进行重试
customer-service.ribbon.OkToRetryOnAllOperations=true
##切换实例的次数
customer-service.ribbon.MaxAutoRetriesNextServer=1
##对当前实例重试的次数
customer-service.ribbon.MaxAutoRetries=2
主入口:
@Bean
@ConfigurationProperties(prefix = "custom.requestFactory")
public HttpComponentsClientHttpRequestFactory customHttpRequestFactory(){
return new HttpComponentsClientHttpRequestFactory();
}
package com.zx.dt2b;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.web.client.RestTemplate;
/**
* Author:码图科技
* Date:2018至今
* 作为服务消费者存在
* Description:版权所有,违者必究
*/
@EnableDiscoveryClient //标识具体的一个服务,需要向注册中心注册
@SpringBootApplication //SpringBoot 核心配置
@EnableRetry //开启重试
public class ErpApplication {
/* @Bean
@LoadBalanced //用于实现内部的服务负载均衡机制: service-id service-name// 如果加了这个注解 , 那么就说明 具有了服务发现的特性 负载均和的机制:意味着可以通过服务名请求数据
public RestTemplate restTemplate(){
HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpComponentsClientHttpRequestFactory.setConnectTimeout(10000);
httpComponentsClientHttpRequestFactory.setConnectionRequestTimeout(10000);
httpComponentsClientHttpRequestFactory.setReadTimeout(20000);
return new RestTemplate(httpComponentsClientHttpRequestFactory);
}*/
@Bean
@ConfigurationProperties(prefix = "custom.requestFactory")
public HttpComponentsClientHttpRequestFactory customHttpRequestFactory(){
return new HttpComponentsClientHttpRequestFactory();
}
@Bean
@LoadBalanced //用于实现内部的服务负载均衡机制: service-id service-name
public RestTemplate restTemplate(){
return new RestTemplate(customHttpRequestFactory());
}
public static void main(String[] args) {
SpringApplication.run(ErpApplication.class, args);
}
}
基于provider进行retry
package com.zx.dt2b.controller;
import com.zx.dt2b.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class RetryController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value="/retry")
public String retry(){
User user = restTemplate.getForObject("http://customer-service/customerservice/getUser?id={1}", User.class, "001");
System.err.println("username: " + user.getName());
return "retry success!";
}
}
restTemplate用法占位方式
User user = restTemplate.getForObject("http://customer-service/customerservice/getUser?id={1}", User.class, "001");
注意实例切换,customer-service.ribbon.MaxAutoRetriesNextServer=1 当重试次数够了还是调用失败,将会切换实例,即切换到另外一个服务名相同的服务。获取数据
新版本不需要设置:hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000
断路器时间要远大于重试时间:请求一次三秒钟,连续失败后,重试三次就是九秒,
切换实例后继续请求如果需要一秒钟,就需要断路器时间10秒钟
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000
断路器的超时时间需要大于ribbon的超时时间,不然不会触发重试。(对于D版本及以前有效)