环境:
jkd:1.8
springcloud: Greenwich.SR1
springboot: 2.1.2.RELEASE
一、棘手的时间设置hystrixTimeout 、 ribbonTimeout、socket-timeout-millis
在 DefaultClientConfigImpl.class
1、public static final int DEFAULT_MAX_AUTO_RETRIES_NEXT_SERVER = 1;//maxAutoRetriesNextServer 默认是1
public static final int DEFAULT_MAX_AUTO_RETRIES = 0;//maxAutoRetries 默认是0
2、在 AbstractRibbonCommand.java 中
//警告的代码
protected static int getHystrixTimeout(IClientConfig config, String commandKey) {
/*...*/
if(hystrixTimeout < ribbonTimeout) {
LOGGER.warn("The Hystrix timeout of " + hystrixTimeout + "ms for the command " + commandKey +
" is set lower than the combination of the Ribbon read and connect timeout, " + ribbonTimeout + "ms.");
}
return hystrixTimeout;
}
//ribbon超时计算
protected static int getRibbonTimeout(IClientConfig config, String commandKey) {
int ribbonTimeout;
if (config == null) {
ribbonTimeout = RibbonClientConfiguration.DEFAULT_READ_TIMEOUT + RibbonClientConfiguration.DEFAULT_CONNECT_TIMEOUT;
} else {
int ribbonReadTimeout = getTimeout(config, commandKey, "ReadTimeout",
IClientConfigKey.Keys.ReadTimeout, RibbonClientConfiguration.DEFAULT_READ_TIMEOUT);
int ribbonConnectTimeout = getTimeout(config, commandKey, "ConnectTimeout",
IClientConfigKey.Keys.ConnectTimeout, RibbonClientConfiguration.DEFAULT_CONNECT_TIMEOUT);
int maxAutoRetries = getTimeout(config, commandKey, "MaxAutoRetries",
IClientConfigKey.Keys.MaxAutoRetries, DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES);
int maxAutoRetriesNextServer = getTimeout(config, commandKey, "MaxAutoRetriesNextServer",
IClientConfigKey.Keys.MaxAutoRetriesNextServer, DefaultClientConfigImpl.DEFAULT_MAX_AUTO_RETRIES_NEXT_SERVER);
ribbonTimeout = (ribbonReadTimeout + ribbonConnectTimeout) * (maxAutoRetries + 1) * (maxAutoRetriesNextServer + 1);
}
return ribbonTimeout;
}
3、比如:配置文件中的配置
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 30000 # 全局熔断超时时长:30000ms
ribbon:
ConnectTimeout: 2000 #ribbon 链接超时时长,默认2000
ReadTimeout: 5000 #ribbon 读取超时时长,默认5000
MaxAutoRetries: 1 #当前服务重试次数,默认0
MaxAutoRetriesNextServer: 1 #切换服务重试次数,默认1
#ribbonTimeout = (ReadTimeout + ConnectTimeout) * (maxAutoRetries + 1) * (maxAutoRetriesNextServer + 1);
30000>(5000+2000) *(1+1)*(1+1)
所以不会报警告。
4.spring.host.socket-timeout-millis 比hixtrix大一点就行了
二、加入验证授权 oauth2
1.直接访问服务不能访问:
原因:oauth2主要是通过token,头部地址里边的东西影响到了访问
解决:
zuul:
sensitive-headers: "*"
2.跨服务访问不了
原因:oauth2在各服务之间使用token当令牌通行,
默认情况下没有开启上下文,各服务之间无法通过授权随意访问
解决:
1). 在各服务yml上添加,不是网关(注意!!!)
feign:
hystrix:
enabled: true
hystrix:
shareSecurityContext: true (默认为false,SecurityContext为会置为null)
2). 接着添加拦截器类,在服务之间的请求头部加上token:
@Configuration
public class FeignOauth2RequestInterceptor implements RequestInterceptor {
private final String AUTHORIZATION_HEADER = "Authorization";
private final String BEARER_TOKEN_TYPE = "bearer";
@Override
public void apply(RequestTemplate template) {
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
if (authentication != null && authentication.getDetails() instanceof OAuth2AuthenticationDetails) {
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails();
template.header(AUTHORIZATION_HEADER, String.format("%s %s", BEARER_TOKEN_TYPE, details.getTokenValue()));
}
}
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
@Bean
public Retryer retry() {
// default Retryer will retry 5 times waiting waiting
// 100 ms per retry with a 1.5* back off multiplier
return new Retryer.Default(100, TimeUnit.SECONDS.toMillis(1), 5);
}
}
3). feign服务调用FeignOauth2RequestInterceptor
@Component
@FeignClient(value = "WEB", configuration = FeignOauth2RequestInterceptor.class, fallback = WebHystrix.class)
public interface WebFeignService {
/**
* GET请求
*
* @return
*/
@RequestMapping(value = "/get", method = RequestMethod.GET)
public Object get();
}
@Component
public class WebHystrix extends BaseHystrix implements WebFeignService {
public static final String FALL_BACK_INFO =
"对不起,%s 服务暂时不可用或者响应时间太长," +
"系统自动进行服务的降级,并熔断该节点微服务的调用。" +
"当检测到该节点微服务调用响应正常后恢复链路。";
@Override
public String getServiceName() {
return "WEB";
}
public Object get() {
return fallBackInfo();
}
protected Object fallBackInfo() {
JSONObject json = new JSONObject();
json.put("name", getServiceName());
json.put("desc", String.format(FALL_BACK_INFO, getServiceName()));
return json;
}
}