spring cloud feign 概述
应用:服务远程调用,具有负载均衡、服务降级等功能
负载均衡策略
轮询:线性轮询可用服务
加权轮询:对服务加权,然后线性轮询
随机:随机调用服务
故障重试轮询:若服务故障可重新轮询
最少连接数:调用当前连接最少的服务
先过滤再轮询:先按照过滤条件过滤服务,再线性轮询
断路器工作原理
请求流程
创建HystrixCommand或者hystrixObservableCommand对象,封装服务调用请求;
判断缓存中是否存储了请求结果,如果有,则直接从缓存中返回结果;
如果没有,判断断路器是否打开,如果断路器打开且不允许单次命令执行,直接服务降级,如果断路器打开且允许单次命令,则执行单次命令,如果命令执行成功,返回命令执行结果,关闭断路器,否则断路器继续打开;
如果断路器关闭,继续判断信号量或者线程池是否已满,如果已满,服务降级;
如果没满则可执行命令,命令执行成功,返回结果,命令执行失败,服务降级;
在命令执行期间,收集命令执行状况信息返回给断路器,供断路器判断打开或者关闭
断路器工作原理
断路器关闭,则允许命令执行;
断路器打开,如果当前时间大于断路器打开时间或者做后一次测试时间+休眠时间,则允许单次命令测试,否则命令不允许执行;
单次命令执行成功,关闭断路器,重设断路器健康状态,否则断路器继续关闭
断路器核心接口
public interface HystrixCircuitBreaker {
boolean allowRequest();
boolean isOpen();
void markSuccess();
public static class NoOpCircuitBreaker implements HystrixCircuitBreaker {
public NoOpCircuitBreaker() {
}
public boolean allowRequest() {
return true;
}
public boolean isOpen() {
return false;
}
public void markSuccess() {
}
}//该断路器实现允许请求,断路器关闭
public static class HystrixCircuitBreakerImpl implements HystrixCircuitBreaker {
private final HystrixCommandProperties properties;
private final HystrixCommandMetrics metrics;
private AtomicBoolean circuitOpen = new AtomicBoolean(false);
private AtomicLong circuitOpenedOrLastTestedTime = new AtomicLong();
protected HystrixCircuitBreakerImpl(HystrixCommandKey key, HystrixCommandGroupKey commandGroup, HystrixCommandProperties properties, HystrixCommandMetrics metrics) {
this.properties = properties;
this.metrics = metrics;
}
public void markSuccess() {
if (this.circuitOpen.get() && this.circuitOpen.compareAndSet(true, false)) {
this.metrics.resetStream();
}
}//当断路器处于半打开状态时使用,如果单次命令调用成功,关闭断路器,重设断路器状态信息
public boolean allowRequest() {
if ((Boolean)this.properties.circuitBreakerForceOpen().get()) {
return false;
} else if ((Boolean)this.properties.circuitBreakerForceClosed().get()) {
this.isOpen();
return true;
} else {
return !this.isOpen() || this.allowSingleTest();
}
}//判断是否允许命令执行,断路器关闭时允许执行,在断路器打开时,如果当前时间超过
最后一次操作时间与休眠时间之和,则允许单词命令执行,否则不允许命令执行
public boolean allowSingleTest() {
long timeCircuitOpenedOrWasLastTested = this.circuitOpenedOrLastTestedTime.get();
return this.circuitOpen.get() && System.currentTimeMillis() > timeCircuitOpenedOrWasLastTested + (long)(Integer)this.properties.circuitBreakerSleepWindowInMilliseconds().get() && this.circuitOpenedOrLastTestedTime.compareAndSet(timeCircuitOpenedOrWasLastTested, System.currentTimeMillis());
}//判断在断路器打开时,是否允许单次命令,如果当前时间超过断路器最后一次打开时间
或者测试时间+休眠时间,则允许单次测试,否则不允许单次命令测试
public boolean isOpen() {
if (this.circuitOpen.get()) {
return true;
} else {
HealthCounts health = this.metrics.getHealthCounts();
if (health.getTotalRequests() < (long)(Integer)this.properties.circuitBreakerRequestVolumeThreshold().get()) {
return false;
} else if (health.getErrorPercentage() < (Integer)this.properties.circuitBreakerErrorThresholdPercentage().get()) {
return false;
} else if (this.circuitOpen.compareAndSet(false, true)) {
this.circuitOpenedOrLastTestedTime.set(System.currentTimeMillis());
return true;
} else {
return true;
}
}
}//根据健康状态信息判断断路器的开关
}
public static class Factory {
private static ConcurrentHashMap<String, HystrixCircuitBreaker> circuitBreakersByCommand = new ConcurrentHashMap();
public Factory() {
}
public static HystrixCircuitBreaker getInstance(HystrixCommandKey key, HystrixCommandGroupKey group, HystrixCommandProperties properties, HystrixCommandMetrics metrics) {
HystrixCircuitBreaker previouslyCached = (HystrixCircuitBreaker)circuitBreakersByCommand.get(key.name());
if (previouslyCached != null) {
return previouslyCached;
} else {
HystrixCircuitBreaker cbForCommand = (HystrixCircuitBreaker)circuitBreakersByCommand.putIfAbsent(key.name(), new HystrixCircuitBreaker.HystrixCircuitBreakerImpl(key, group, properties, metrics));
return cbForCommand == null ? (HystrixCircuitBreaker)circuitBreakersByCommand.get(key.name()) : cbForCommand;
}
}
public static HystrixCircuitBreaker getInstance(HystrixCommandKey key) {
return (HystrixCircuitBreaker)circuitBreakersByCommand.get(key.name());
}
static void reset() {
circuitBreakersByCommand.clear();
}
}//断路器工厂,维护断路器标识与断路器的对应关系
}