1,默认不开启,开启hystrix熔断器后,发现下游服务器并没有问题,但是一直走熔断降级方法
# To disable Hystrix in Feign
feign:
hystrix:
enabled: true
解决方法
首先把Hystrix 在配置文件中的配置全部注释掉
server:
port: 80
eureka:
client:
serviceUrl:
defaultZone: http://localhost:9999/eureka/
#表示多久去注册中心拉取一次服务信息
registry-fetch-interval-seconds: 30
fetch-registry: true
#Eureka客户端向服务端发送心跳时间的间隔,单位为秒(默认是30秒)
instance:
#向注册中心发起心跳
lease-renewal-interval-in-seconds: 1
spring:
application:
name: user-consumers
user-providers:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
ConnectTimeout: 10000 # 连接超时时间
ReadTimeout: 10000 # 数据读取超时时间,连接之后,数据传输过程
MaxAutoRetries: 1 # 最大重试次数(第一个服务)
MaxAutoRetriesNextServer: 1 # 最大重试下一个服务次数(集群的情况才会用到)
OkToRetryOnAllOperations: false # 是否对所有的请求都重试
eager-load:
enabled: true
logging:
level:
com.angen.controller: debug
#默认是ZoneAvoidanceRule
#service-provider-user这个是对应的微服务的名字
#
#service-provider-user:
# ribbon:
# NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
#hystrix:
# command:
# default:
# circuitBreaker:
# #强制打开熔断器,默认是false
# forceOpen: true
# #触发熔断错误比例阈值,默认是50%
# errorThresholdPercentage: 50
# #熔断后休眠时长,默认是5000毫秒
# sleepWindowInMilliseconds: 10000
# #熔断触发最小请求次数,默认值是20
# requestVolumeThreshold: 10
# execution:
# isolation:
# #strategy: SEMAPHORE
# thread:
# #熔断超时设置,默认是1000毫秒
# timeoutInMilliseconds: 10000
# To disable Hystrix in Feign
feign:
hystrix:
enabled: true
httpclient:
connection-timeout: 10000
client:
config:
default:
#连接到目标的时间,此处会收到注册中心启动中的影响。设置为3秒钟,如果注册中心有明显的不在线,基本是毫秒级熔断拒绝
connectTimeout: 3000
#获取目标连接后执行的最长时间,设置为32秒,即服务最长时
readTimeout: 32000
然后自己定义配置文件
package com.angen.config;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;
import feign.Feign;
import feign.Target;
import feign.hystrix.SetterFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.lang.reflect.Method;
@Configuration
public class FeignSupportConfig {
@Bean
public SetterFactory setterFactory(){
SetterFactory setterFactory =new SetterFactory() {
@Override
public HystrixCommand.Setter create(Target<?> target, Method method) {
String groupKey = target.name();
String commandKey = Feign.configKey(target.type(), method);
HystrixCommandProperties.Setter setter = HystrixCommandProperties.Setter()
//设置统计指标60秒为一个时间窗口
.withMetricsRollingStatisticalWindowInMilliseconds(1000 * 60)
//超过80%失败率
.withCircuitBreakerErrorThresholdPercentage(80)
//操作5个开启短路器
.withCircuitBreakerRequestVolumeThreshold(5)
//设置线程隔离
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
//设置断路器的开启时间为60秒
.withCircuitBreakerSleepWindowInMilliseconds(1000 * 60);
return HystrixCommand.Setter
.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
.andCommandKey(HystrixCommandKey.Factory.asKey(commandKey))
.andCommandPropertiesDefaults(setter);
}
};
return setterFactory;
}
}
然后
重写一下HystrixConcurrencyStrategy
原因大家可以看以下这个文章
Feign开启HyStrix后如何配置线程隔离及熔断策略_问题不太大的博客-CSDN博客_feign hystrix自定义隔离
package com.angen.feign;
import com.netflix.hystrix.HystrixThreadPoolKey;
import com.netflix.hystrix.HystrixThreadPoolProperties;
import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle;
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;
import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook;
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;
import com.netflix.hystrix.strategy.properties.HystrixProperty;
import org.apache.commons.logging.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Component
public class RequestAttributeHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
private static final Log log = LogFactory.getLog(RequestAttributeHystrixConcurrencyStrategy.class);
private HystrixConcurrencyStrategy delegate;
public RequestAttributeHystrixConcurrencyStrategy() {
try {
this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy();
if (this.delegate instanceof RequestAttributeHystrixConcurrencyStrategy) {
// Welcome to singleton hell...
return;
}
HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins
.getInstance().getCommandExecutionHook();
HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance()
.getEventNotifier();
HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance()
.getMetricsPublisher();
HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance()
.getPropertiesStrategy();
this.logCurrentStateOfHystrixPlugins(eventNotifier, metricsPublisher,
propertiesStrategy);
HystrixPlugins.reset();
HystrixPlugins.getInstance().registerConcurrencyStrategy(this);
HystrixPlugins.getInstance()
.registerCommandExecutionHook(commandExecutionHook);
HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
}
catch (Exception e) {
log.error("Failed to register Sleuth Hystrix Concurrency Strategy", e);
}
}
private void logCurrentStateOfHystrixPlugins(HystrixEventNotifier eventNotifier,
HystrixMetricsPublisher metricsPublisher,
HystrixPropertiesStrategy propertiesStrategy) {
if (log.isDebugEnabled()) {
log.debug("Current Hystrix plugins configuration is ["
+ "concurrencyStrategy [" + this.delegate + "]," + "eventNotifier ["
+ eventNotifier + "]," + "metricPublisher [" + metricsPublisher + "],"
+ "propertiesStrategy [" + propertiesStrategy + "]," + "]");
log.debug("Registering Sleuth Hystrix Concurrency Strategy.");
}
}
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
return new WrappedCallable<>(callable, requestAttributes);
}
@Override
public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,
HystrixProperty<Integer> corePoolSize,
HystrixProperty<Integer> maximumPoolSize,
HystrixProperty<Integer> keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
return this.delegate.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize,
keepAliveTime, unit, workQueue);
}
@Override
public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,
HystrixThreadPoolProperties threadPoolProperties) {
return this.delegate.getThreadPool(threadPoolKey, threadPoolProperties);
}
@Override
public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) {
return this.delegate.getBlockingQueue(maxQueueSize);
}
@Override
public <T> HystrixRequestVariable<T> getRequestVariable(
HystrixRequestVariableLifecycle<T> rv) {
return this.delegate.getRequestVariable(rv);
}
static class WrappedCallable<T> implements Callable<T> {
private final Callable<T> target;
private final RequestAttributes requestAttributes;
public WrappedCallable(Callable<T> target, RequestAttributes requestAttributes) {
this.target = target;
this.requestAttributes = requestAttributes;
}
@Override
public T call() throws Exception {
try {
RequestContextHolder.setRequestAttributes(requestAttributes);
return target.call();
}
finally {
RequestContextHolder.resetRequestAttributes();
}
}
}
}
如果这样还不生效配置,那么
还得在feign接口上载入配置文件configuration = FeignSupportConfig.class
@FeignClient(name = "user-providers",
fallback = UserFeignImpl.class,
path = "/user",
configuration = FeignSupportConfig.class)
public interface UserFeign {
/*
* 这个路径对应请求微服务的路径
* */
@RequestMapping(method = RequestMethod.GET,value = "/{id}")
public User feignFindById(@PathVariable("id") Integer id);
}