Spring Cloud Hystrix服务容错保护学习笔记(一)

服务容错保护 Spring Cloud Hystrix

引入依赖

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

@EnableCircuitBreaker注解与@SpringCloudApplication

//@EnableCircuitBreaker
//@EnableDiscoveryClient
//@SpringBootApplication
@SpringCloudApplication
public class RibbonConsumerApplication {

    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(RibbonConsumerApplication.class,args);
    }
}

指定回调方法

@Service
public class UserService {
    @Autowired
    RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "defaultSec")
    private String defaultUser(){
        return restTemplate.getForObject("http://user-server/users/{1}",User.class,id);
    }
    
    public String defaultSec(){
        return "error";
    }
}
1.原理-工作流程

(1)创建HystruxCommand或HystrixObservableComand对象
命令模式

(2)命令执行
RxJava观察者订阅者模式

private void RxJava(){
        // 创建事件源observable
        Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("Hello RxJava");
                subscriber.onNext("Im 程序员 haha");
                subscriber.onCompleted();
            }
        });

        // 创建订阅者
        Subscriber<String> subscriber = new Subscriber<String>() {
            @Override
            public void onCompleted() {
            }

            @Override
            public void onError(Throwable throwable) {
            }

            @Override
            public void onNext(String s) {
                System.out.println("subscriber:" + s);
            }
        };

        // 订阅
        observable.subscribe(subscriber);
    }

(3)结果是否被缓存

(4)断路器是否断开

(5)线程池、请求队列、信号量是否占满

(6)HystrixObservableComand.construct()或Hystrix.run()

(7)计算断路器健康度

(8)fallback处理

服务降级:当命令执行失败的时候,Hystrix会进入fallback尝试回退处理

(9)返回成功的响应

2.断路器原理
public interface HystrixCircuitBreaker {
    boolean allowRequest();

    boolean isOpen();

    void markSuccess();

    public static class NoOpCircuitBreaker implements HystrixCircuitBreaker {
        // ...
    }
    public static class HystrixCircuitBreakerImpl implements HystrixCircuitBreaker {
        // ...
    }
    public static class Factory {
       // ...
    }
}

allowRequest():每个Hystrix命令的请求都通过它判断是否被执行

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();
    }
}

通过设置休眠时间,allowSingleTest()方法,在断路器打开设置的时间(默认5秒),休眠时间到达之后再次请求尝试访问,处于”半开“状态,请求成功,则断路器关闭,请求失败,则继续打开。

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());
}

isOpen():返回当前断路器是否打开

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;
        }
    }
}

markSuccess():用来闭合断路器

public void markSuccess() {
    if (this.circuitOpen.get() && this.circuitOpen.compareAndSet(true, false)) {
        this.metrics.resetStream();
    }
}

该函数在“半开路”时候使用,若Hystrix命令调用成功,调用此方法关闭断路器,重置度量指标对象。

在这里插入图片描述

3.依赖隔离

舱壁模式

Hystrix使用舱壁模式实现线程池的隔离,它会为每一个依赖服务创建独立的线程池。自身完全保护,有效降低新服务风险,快速查找解决问题,不停服务解决,应用更加灵活

Hystrix信号量:控制单个依赖服务并发度

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值