SpringCloud---Hystrix---Dashboard---TurBine(断路器、监控)

介绍

现在我们假设一下,服务提供者响应非常缓慢,那么消费者对提供者的请求就会被强制等待,直到服务返回。在高负载场景下,如果不做任何处理,这种问题很可能造成所有处理用户请求的线程都被耗竭,而不能响应用户的进一步请求。

雪崩效应

在微服务架构中通常会有多个服务层调用,大量的微服务通过网络进行通信,从而支撑起整个系统,各个微服务之间也难免存在大量的依赖关系。更何况每个服务都不是100%可用的,网络往往也是脆弱的,所以难免有些请求会失败,基础服务的故障导致【级联故障】,进而造成了整个系统的不可用,这种现象被称为雪崩效应,直接了当的讲,服务雪崩效应描述的是一种因服务提供者的不可用导致服务消费者的不可用,并将不可用逐渐扩大的过程。


雪崩效应.png

C、D服务依赖B服务,B服务依赖A服务,如果A服务的不可用导致B服务慢慢的也不可用,B逐渐导致D、C不可用,这样逐渐扩大,导致整个系统的瘫痪。

解决方案

  1. 超时机制
    通过网络请求其他服务时,都必须设置超时。正常情况下,一个远程调用一般在几十毫秒内就返回了。当依赖的服务不可用,或者因为网络问题,响应时间将会变得很长(几十秒)。而通常情况下,一次远程调用对应了一个线程/进程,如果响应太慢,那这个线程/进程就会得不到释放。而线程/进程都对应了系统资源,如果大量的线程/进程得不到释放,并且越积越多,服务资源就会被耗尽,从而导致资深服务不可用。所以必须为每个请求设置超时。
  2. 断路器模式
    试想一下,家庭里如果没有断路器,电流过载了(例如功率过大、短路等),电路不断开,电路就会升温,甚至是烧断电路、起火。有了断路器之后,当电流过载时,会自动切断电路(跳闸),从而保护了整条电路与家庭的安全。当电流过载的问题被解决后,只要将关闭断路器,电路就又可以工作了。
    同样的道理,当依赖的服务有大量超时,再让新的请求去访问已经没有太大意义,只会无谓的消耗现有资源。譬如我们设置了超时时间为1秒,如果短时间内有大量的请求,在1秒内都得不到响应,就往往意味着异常。此时就没有必要让更多的请求去访问这个依赖了,我们应该使用断路器避免资源浪费。

断路器(Hystrix)

  1. 断路器可以实现快速失败,如果它在一段时间内侦测到许多类似的错误(如超时),就会强迫其以后的多个调用【快速失败】,不再请求所依赖的服务,从而防止应用程序不断地尝试执行可能会失败的操作,这样应用程序可以继续执行而不用等待修正错误,或者浪费CPU时间去等待长时间的超时。
  2. 断路器也可以使应用程序能够诊断错误是否已经修正,如果已经修正,应用程序会再次尝试调用操作。断路器模式就像是那些容易导致错误的操作的一种代理。这种代理能够记录最近调用发生错误的次数,然后决定使用允许操作继续,或者立即返回错误。
    断路器.png

    简单解释一下:

    1. 关闭:如果一个请求一直都是成功的,那么断路器是关闭的;
    2. 打开:如果一个请求失败率达到了阈值,断路器会打开;
    3. 半开:在断路器打开的同时,它会【分流】,就是将请求的一小部分放开,让他去请求,如果失败率低于阈值,就会关闭断路器,如果还是高于阈值,继续保持在打开状态【快速失败】。

Hystrix

介绍

针对上述问题,Spring Cloud Hystrix实现了断路器、线程隔离等一系列保护功能,他也是基于Netflix的开源框架Hystrix实现的,该框架的目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供强大的容错能力,Hystrix具备服务降级、服务熔断、线程和信号的隔离、请求缓存、请求合并以及服务监控等强大功能。

具体实现

  1. 普通实现

    1. 启动类添加@EnableCircuitBreaker注解
    @SpringBootApplication
    @EnableEurekaClient
    @EnableFeignClients
    @EnableCircuitBreaker
    public class MovieConsumeApplication {
          public static void main(String[] args) {
          SpringApplication.run(MovieConsumeApplication.class, args);
        }
    }
    
    
    1. 添加注解@HystrixCommand和fallback方法(@HystrixCommand(fallbackMethod = "getDefaultMovide"))
    @RestController
    public class MovieController {
    
    @Autowired
    private UserClient userClient;
    
    @GetMapping("/movie/{id}")
    @HystrixCommand(fallbackMethod = "getDefaultMovide")
    public User getMovide(@PathVariable long id) {
         return userClient.getUser(id);
    }
    
    public User getDefaultMovide(long id) {
        User user = new User();
        user.setId(-1L);
        user.setName("失败");
        user.setAge(-1);
        user.setAddress("未知");
        return user;
      }
    }
    

    完事,就这么简单

  2. feign配合使用hystrix

    这里我直接介绍指定Client添加Hystrix,下面代码的前提是:我有来个服务提供者user-provider、payment-provide,我将让user使用Hystrix,payment不使用Hystrix.

    1. yml中添加

      feign:
          hystrix:
              enabled: true
      

      默认说是开启的,刚开始没有添加,死活不走fallback,最后添加 上好了,我也很迷茫

    2. Client、FallBack代码

      • UserClient

          @FeignClient(name = "user-provider",fallback =     HystrixClientFallback.class)
          public interface UserClient {
            @RequestMapping(value = "/getUser/{id}", method = RequestMethod.GET)
            public User getUser(@PathVariable("id") long id);
        
          }
        
      • User的Fallback类(这个类名不规范)

         @Component
         public class HystrixClientFallback implements UserClient {
        
          @Override
          public User getUser(@PathVariable("id") long id) {
              User user = new User();
              user.setName("123");
              return user;
          }
        
        }
        
      • PaymentClient

        @FeignClient(name = "payment-provide", configuration = PaymentConfig.class, fallback = PaymentClientFallback.class)
        public interface PaymentClient {
        
          @RequestMapping(value = "/getPayment/{id}", method = RequestMethod.GET)
          public Payment getPayment(@PathVariable("id") long id);
        }
        
      • PaymentClientFallback

        @Component
        public class PaymentClientFallback implements PaymentClient {
          @Override
          public Payment getPayment(@PathVariable long id) {
          Payment payment = new Payment();
          payment.setId(-1);
          payment.setManay(-1);
          payment.setUserId(-1);
          return payment;
          }
        }
        
      • PaymentConfig

        @Configuration
        public class PaymentConfig {
          @Bean
          @Scope("prototype")
          public Feign.Builder feignBuilder() {
              return Feign.builder();
          }
        }
        

        注意:PaymentConfig这个类放【不能】放到到【启动类】所在【包】或是【所在包的子包下】,不然所有Client都会不使用Hystrix。

        • Controller
        @RestController
        public class MovieController {
        
          @Autowired
          private UserClient userClient;
          @Autowired
          private PaymentClient paymentClient;
        
          @GetMapping("/movie/{id}")
          public User getMovide(@PathVariable long id) {
            return userClient.getUser(id);
          }
        
          @GetMapping("/getPayment/{id}")
          public Payment allMovie(@PathVariable long id) {
              return paymentClient.getPayment(id);
          }
        }
        

    结果:http://localhost:8002/movie/1 返回Fallback结果
    http://localhost:8002/getPayment/1 报错

  3. 使用FallbackFactory这个我们只使用user-provider

    • 添加fallbackFactory = UserFallbackFactory.class
    @FeignClient(name = "user-provider", fallbackFactory = UserFallbackFactory.class)
    public interface UserClient {
    
       @RequestMapping(value = "/getUser/{id}", method = RequestMethod.GET)
       public User getUser(@PathVariable("id") long id);
    
    }
    
    
    • UserFallbackFactory
    @Component
    public class UserFallbackFactory implements   FallbackFactory<UserClient> {
    
       Logger logger = LoggerFactory.getLogger(UserFallbackFactory.class);
    
       @Override
       public UserClient create(Throwable throwable) {
           logger.info(" User getUser(@PathVariable() long id)" + throwable.getMessage());
           return new UserClient() {
               @Override
               public User getUser(@PathVariable("id") long id) {
                   User user = new User();
                   user.setName("falbackFactory");
                   return user;
               }
           };
       }
    }
    

    FallbackFactroy相当于Fallback的增强版,可以在调用fallback方法前作一些处理

Hystrix Dashboard(断路器监控)

介绍
 在微服务架构中为例保证程序的可用性,防止程序出错导致网络阻塞,出现了断路器模型。断路器的状况反应了一个程序的可用性和健壮性,它是一个重要指标。Hystrix Dashboard是作为断路器状态的一个组件,提供了数据监控和友好的图形化界面。

实现

  1. 创建Model
    1. yml中设置端口
    ```
     server:
       port: 8030
    ```
    
    1. 启动类添加注解 @EnableHystrixDashboard
     @SpringBootApplication
     @EnableHystrixDashboard
     public class HystrixDashboardApplication {
    
       public static void main(String[] args) {
           SpringApplication.run(HystrixDashboardApplication.class, args);
       }
    }
    

  1. 访问 http://localhost:8030/hystrix
    dash.png

按要求输入http://localhost:8002/hystrix.stream等信息

hystrix-dashboard-3.png

可以监控Hystrix

注意:出来这个图的前提是http://localhost:8002/hystrix.stream能访问的通,如果访问不通需要注意,启动类是否加了@EnableCircuitBreaker,

Hystrix Turbine

  1. 介绍
    Turbine好似Bashboard加强版,Bashboard每次监控一个服务,但是Turbine却能同时监控多个服务,
  2. 具体实现
    1. 启动类添加注解
      @SpringBootApplication
      @EnableTurbine
      public class HystrixTurbineApplication {
      
          public static void main(String[] args) {
              SpringApplication.run(HystrixTurbineApplication.class, args);
          }
      }
      
    2. yml添加相应配置
      eureka:
        client:
          serviceUrl:
            defaultZone: http://ralap:hjx969190@localhost:8761/eureka/
        instance:
          prefer-ip-address: true
      server:
        port: 8040
      turbine:
        aggregator:
          clusterConfig: default
        appConfig: movie-consume-feign-hystrix,movie-consume
        cluster-name-expression: "'default'"
      spring:
        application:
          name: hystrix-turbine
      

    appConfig:配置监控的applicationName
    clusterConfig: applicationName 全部大写,这里使用的default,配合cluster-name-expression使用,
    cluster-name-expression:获取集群的名称

分布式.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,099评论 18 139
  • 一. Java基础部分.................................................
    wy_sure阅读 3,731评论 0 11
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,293评论 18 399
  • 本篇文章为Spring Cloud 各模块演示代码的分支[Hystrix]部分。先从几个概念开始,了解概念有助于对...
    maven_hz阅读 1,072评论 1 0
  • 前两天孩子回家说妈妈老师让家长写一篇关于无烟生活的日记,说实话,真是愁着写,可是为了孩子为了我们的下一代...
    刘雪妈妈阅读 305评论 0 0