spring cloud feign 概述


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();
        }
    }//断路器工厂,维护断路器标识与断路器的对应关系
}

              

                       

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值