zoukankan      html  css  js  c++  java
  • 跳闸了啊! 服务容灾:熔断器简介

    雪崩效应

    现如今SOA、微服务风愈演愈烈,越来越多的业务和资源被以服务的形式包装和发布,服务间又可能会依赖其他各种服务。由此而来不可避免的会产生很多问题。

    比如一个服务,其依赖了另外30个服务。假设每个服务的可用率都有三个9(99.9%),那么我们计算一下:

    99.99%^30 = 99.7%

    现实很残酷,这个服务的实际可用性只能是99.7%,也就是说每个月这个服务都要好宕机8000+秒~~~


    正常用户请求时,服务内部依次请求APHI服务,兵返回响应结果。


    非常不幸,我们的I服务出了某些问题,此时我们的用户请求就被堵塞在I服务处。


    更加悲剧的是,后续越来越多的请求都被堵塞在I服务处,而这些被堵塞的请求会占用线程、IO、网络等系统资源,随着资源被占用的越来越多,本来不存在的性能问题也会随之而来,造成系统中的其他服务出现问题,甚至导致系统奔溃。

    这也就是我们常说的雪崩效应


    服务容灾

    为了避免出现服务的雪崩,我们需要对服务做容灾处理。

    常规的服务容灾处理思路有:

    • 资源隔离
    • 超时设定
    • 服务降级
    • 服务限流

    其中每种思路又可以有不同的解决方案。

    比如资源隔离可以通过将不同的服务发布在独立的docker容器或服务器中,这样即使一个服务出现问题,也不会殃及池鱼。

    服务降级和服务限流可以通过前端nginx+lua来实现,当服务处理延迟或宕机时,nginx可以直接返回固定的降级/失败响应,已快速跳过问题服务。


    Hystrix

    Hystrix,是Netflix的一个开源熔断器,通过Hystrix,我们可以很方便的实现资源隔离、限流、超时设计、服务降级等服务容灾措施,并且还提供了强大的监控,可以查看各个熔断器的允许情况。

    通过上图,可以看出,Hystrix提供了一个HystrixCommand用来包装调用请求。HystrixCommand的执行流程大概如下:
    1.首先检查缓存中是否有结果。如果有则直接返回缓存结果。
    2.判断断路器是否开启,如果断路器闭合,执行降级业务逻辑并返回降级结果。
    3.判断信号量/线程池资源是否饱和,如饱和则执行降级业务逻辑并返回降级结果。
    4.调用实际服务,如发生异常,执行降级业务逻辑并返回降级结果,并调整断路器阈值。
    5.判断实际业务是否超时,超时则返回超时响应结果,并调整断路器阈值。

    了解了流程,来看下如何使用Hystrix。首先我们需要定义一个命令类来包装我们的业务调用:

    //继承HystrixCommand
    public class CommandHelloFailure extends HystrixCommand<String> {
    
        private final String name;
    
        public CommandHelloFailure(String name) {
    		//设置分组key,分组key可以用在报表、监控中,默认的线程池隔离也基于分组key
             super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
    			//指定命令key,可
                .andCommandKey(HystrixCommandKey.Factory.asKey("HelloWorld"))
    			//指定线程池key,取代默认的分组key
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("HelloWorldPool")));
    		/*
    		//线程池隔离模式,不写默认是线程池隔离模式
    		HystrixCommandProperties.Setter()
    		   .withExecutionIsolationStrategy(ExecutionIsolationStrategy.THREAD)
    		//信号量隔离模式
    		HystrixCommandProperties.Setter()
    		   .withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE)
    		//超时时间,默认1秒
    		HystrixCommandProperties.Setter()
    		   .withExecutionTimeoutInMilliseconds(int value)  
    		//信号量模式下,最大并发请求限流,默认值10
    		HystrixCommandProperties.Setter()
    		   .withFallbackIsolationSemaphoreMaxConcurrentRequests(int value)  
    		//熔断器阈值,默认20
    		HystrixCommandProperties.Setter()
    			.withCircuitBreakerRequestVolumeThreshold(int value)
    		//熔断器关闭时间,默认5秒
    		HystrixCommandProperties.Setter()
    			.withCircuitBreakerSleepWindowInMilliseconds(int value)
    		*/
            this.name = name;
        }
    
        @Override
    	//执行实际服务,这里模拟全部返回异常
        protected String run() {
            throw new RuntimeException("this command always fails");
        }
    
        @Override
    	//执行降级业务
        protected String getFallback() {
            return "Hello Failure " + name + "!";
        }
    
    	@Override
    	//从缓存中获取
        protected String getCacheKey() {
            ...
        }
    } 
    

    使用这个命令类也非常简单:

    //同步执行
    String s = new CommandHelloWorld("Bob").execute();
    //异步执行
    Future<String> s = new CommandHelloWorld("Bob").queue();
    //响应式
    Observable<String> s = new CommandHelloWorld("Bob").observe();
    

    通过Hystrix提供的监控界面,我们可以观察到各个熔断器的执行情况:

    更多说明和例子可以查看Hystrix的wiki


    Hystrix和Spring boot

    想在spring boot中使用Hystrix就更加简单了,只需要引入spring-cloud-starter-hystrix,

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

    然后添加注解使用Hystrix
    @EnableCircuitBreaker
    @EnableHystrixDashboard

    最后在需要使用熔断器的地方标记注解即可。

    @HystrixCommand(groupKey = "xxx", fallbackMethod = "yyy")
    public String doSomething() 
    

    遥想2015年9月7日,上交所、深交所、中金所宣布,拟在保留现有个股涨跌幅制度前提下,引入指数熔断机制。随后A股联系两天下跌熔断,提前收盘。其中这里的熔断机制和我们今天讨论的熔断器思路一致,但是反而导致了A股暴跌,这也说明了我们还是得从根源产出高可用的服务,而不是依赖某些外部措施帮助我们提高可用性。同时说明了A股比咱写的垃圾服务更加不可靠,还是安心当个码农吧。

    最后,就问各位童鞋,敢不敢点个赞~~~~

    参考资料:
    https://github.com/Netflix/Hystrix
    http://www.cnblogs.com/jesse2013/p/things-architect-must-know.html

  • 相关阅读:
    Azure 虚拟机安全加固整理
    AzureARM 使用 powershell 扩容系统磁盘大小
    Azure Linux 云主机使用Root超级用户登录
    Open edX 配置 O365 SMTP
    powershell 根据错误GUID查寻错误详情
    azure 创建redhat镜像帮助
    Azure Powershell blob中指定的vhd创建虚拟机
    Azure Powershell 获取可用镜像 PublisherName,Offer,Skus,Version
    Power BI 连接到 Azure 账单,自动生成报表,可刷新
    Azure powershell 获取 vmSize 可用列表的命令
  • 原文地址:https://www.cnblogs.com/lazio10000/p/6027581.html
Copyright © 2011-2022 走看看