zoukankan      html  css  js  c++  java
  • Spring Cloud学习笔记【四】断路器Hystrix

    雪崩效应

    在微服务架构中通常会有多个服务层调用,基础服务的故障可能会导致级联故障,进而造成整个系统不可用的情况,这种现象被称为服务雪崩效应。服务雪崩效应是一种因 “服务提供者” 的不可用导致 “服务消费者” 的不可用, 并将不可用逐渐放大的过程。
    如果下图所示:A 作为服务提供者,B 为 A 的服务消费者,C 和 D 是 B 的服务消费者。A 不可用引起了 B 的不可用,并将不可用像滚雪球一样放大到 C 和 D 时,雪崩效应就形成了。

    断路器

    Netflix 创建了一个名为 Hystrix 的库, 实现了断路器的模式。“断路器” 本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。

    当然,在请求失败频率较低的情况下,Hystrix 还是会直接把故障返回给客户端。只有当失败次数达到阈值时,断路器打开并且不进行后续通信,而是直接返回备选响应。当然,Hystrix 的备选响应也是可以由开发者定制的。

    Ribbon 整合 Hystrix

    新建spring start project,导入依赖

     1 <dependencies>
     2    <dependency>
     3        <groupId>org.springframework.boot</groupId>
     4        <artifactId>spring-boot-starter-web</artifactId>
     5    </dependency>
     6    <dependency>
     7        <groupId>org.springframework.cloud</groupId>
     8        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
     9    </dependency>
    10    <dependency>
    11        <groupId>org.springframework.cloud</groupId>
    12        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    13    </dependency>
    14    <dependency>
    15        <groupId>org.springframework.cloud</groupId>
    16        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    17    </dependency>
    18</dependencies>

    属性配置(application.yml)

    server:
      port: 9001
    spring:
      application:
        name: service-hystrix-ribbon
    eureka:
      client:
        serviceUrl:
          defaultZone: http://admin:123456@localhost:8761/eureka/

    开启hystrix功能,在启动类上加上@EnableHystrix注解

     1 package com.carry.springcloud;
     2 
     3 import org.springframework.boot.SpringApplication;
     4 import org.springframework.boot.autoconfigure.SpringBootApplication;
     5 import org.springframework.cloud.client.loadbalancer.LoadBalanced;
     6 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
     7 import org.springframework.cloud.netflix.hystrix.EnableHystrix;
     8 import org.springframework.context.annotation.Bean;
     9 import org.springframework.web.client.RestTemplate;
    10 
    11 @EnableHystrix
    12 @EnableEurekaClient
    13 @SpringBootApplication
    14 public class ServiceHystrixRibbonApplication {
    15 
    16     public static void main(String[] args) {
    17         SpringApplication.run(ServiceHystrixRibbonApplication.class, args);
    18     }
    19 
    20     @Bean
    21     @LoadBalanced
    22     RestTemplate restTemplate() {
    23         return new RestTemplate();
    24     }
    25 }

    添加fallback方法

    package com.carry.springcloud.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
    
    @RestController
    public class RibbonController {
    
        @Autowired
        RestTemplate restTemplate;
    
        @Value("${server.port}")
        String port;
    
        @GetMapping("/getPoducerInfo")
        @HystrixCommand(fallbackMethod = "getPoducerInfoFallback")
        public String getPoducerInfo() {
            String result = this.restTemplate.getForObject("http://service-producer/getPortInfo", String.class);
            return result;
        }
        
        public String getPoducerInfoFallback(){
            return "getPoducerInfo异常,端口:" + port;
        }
    }

    测试

    依次启动eureka-server、service-producer、service-hystrix-ribbon,如下图成功注册到eureka

    访问localhost:9001/getPoducerInfo,结果轮询显示8080与8081,停掉8081

    接着访问localhost:9001/getPoducerInfo,当访问到8081时出现以下结果,说明服务降级调用了fallback方法

    Feign 整合 Hystrix

    新建项目并导入依赖

     1 <dependencies>
     2    <dependency>
     3        <groupId>org.springframework.boot</groupId>
     4        <artifactId>spring-boot-starter-web</artifactId>
     5    </dependency>
     6    <dependency>
     7        <groupId>org.springframework.cloud</groupId>
     8        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
     9    </dependency>
    10    <dependency>
    11        <groupId>org.springframework.cloud</groupId>
    12        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    13    </dependency>
    14    <dependency>
    15        <groupId>org.springframework.cloud</groupId>
    16        <artifactId>spring-cloud-starter-openfeign</artifactId>
    17    </dependency>
    18</dependencies>

    配置属性

    server:
      port: 9002
    spring:
      application:
        name: service-hystrix-feign
    eureka:
      client:
        serviceUrl:
          defaultZone: http://admin:123456@localhost:8761/eureka/
    feign: 
      hystrix: 
        enabled: true

    启动类开启Feign支持

     1 package com.carry.springcloud;
     2 
     3 import org.springframework.boot.SpringApplication;
     4 import org.springframework.boot.autoconfigure.SpringBootApplication;
     5 import org.springframework.cloud.openfeign.EnableFeignClients;
     6 
     7 @EnableFeignClients
     8 @SpringBootApplication
     9 public class ServiceHystrixFeignApplication {
    10 
    11     public static void main(String[] args) {
    12         SpringApplication.run(ServiceHystrixFeignApplication.class, args);
    13     }
    14 }

    添加Feign接口

     1 package com.carry.springcloud.api;
     2 
     3 import org.springframework.cloud.openfeign.FeignClient;
     4 import org.springframework.web.bind.annotation.GetMapping;
     5 
     6 import com.carry.springcloud.fallback.ConsumerFeignFallback;
     7 
     8 @FeignClient(name = "service-producer", fallback = ConsumerFeignFallback.class)
     9 public interface ConsumerFeignClient {
    10 
    11     @GetMapping("/getPortInfo")
    12     public String produce();
    13 }

    添加fallback类

     1 package com.carry.springcloud.fallback;
     2 
     3 import org.springframework.stereotype.Component;
     4 
     5 import com.carry.springcloud.api.ConsumerFeignClient;
     6 
     7 @Component
     8 public class ConsumerFeignFallback implements ConsumerFeignClient {
     9 
    10     @Override
    11     public String produce() {
    12         return "服务调用失败!";
    13     }
    14 
    15 }

    控制层注入Feign接口

     1 package com.carry.springcloud.controller;
     2 
     3 import org.springframework.beans.factory.annotation.Autowired;
     4 import org.springframework.web.bind.annotation.GetMapping;
     5 import org.springframework.web.bind.annotation.RestController;
     6 
     7 import com.carry.springcloud.api.ConsumerFeignClient;
     8 
     9 @RestController
    10 public class ConsumerController {
    11     
    12     @Autowired
    13     private ConsumerFeignClient feignClient;
    14     
    15     @GetMapping("/getPoducerInfoByFeign")
    16     public String getPoducerInfoByFeign() {
    17         return feignClient.produce();
    18     }
    19 
    20 }

    测试

     测试方法同上不再赘述

  • 相关阅读:
    ios开发启动页面
    C++再学习之路(五)
    C++再学习之路(四)
    opencv再学习之路(九)---制作对焦图像
    opencv再学习之路(八)---轮廓检测
    C++再学习之路---例程(一) 文本查询
    opencv再学习之路(五)---灰度直方图显示
    opencv再学习之路(七)---图像单个元素的访问
    opencv再学习之路(六)---模板匹配
    C++再学习之路(三)
  • 原文地址:https://www.cnblogs.com/carrychan/p/9479637.html
Copyright © 2011-2022 走看看