spring-cloud-hystrix服务熔断与降级

  Hystrix是一个用于处理分布式系统的延迟容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时,异常等,Hystrix能保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。

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

  在大中型分布式系统中,通常系统很多依赖(HTTP,hession,Netty,Dubbo等),如下图:

   在高并发访问下,这些依赖的稳定性与否对系统的影响非常大,但是依赖有很多不可控问题:如网络连接缓慢,资源繁忙,暂时不可用,服务脱机等.

   如下图:QPS为50的依赖 I 出现不可用,但是其他依赖仍然可用.

  当依赖I 阻塞时,大多数服务器的线程池就出现阻塞(BLOCK),影响整个线上服务的稳定性.如下图:

  在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败。高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险。

  解决问题方案:对依赖做隔离,Hystrix就是处理依赖隔离的框架,同时也是可以帮我们做依赖服务的治理和监控.

服务熔断:

  熔断机制是应对雪崩效应的一种微服务链路保护机制。

  当扇出链路(即上面的图二)的某个微服务(I)不可用或者响应时间太长,会进行服务的降级,进而熔断该节点微服务的调用,快速返回"错误"的响应信息。当检测到该节点微服务调用响应正常回复后恢复调用链路。在springCloud框架里熔断机制通过Hystrix实现。Hystrix会监控微服务服务间调用的状况,当失败的调用到达一定的阈值,缺省是5秒内20次调用失败就会启动熔断机制,熔断机制的注解是 @HystrixCommand

1.pom文件修改 添加以下依赖

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR3</spring-cloud.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <!-- SpringCloud 所有子项目 版本集中管理. 统一所有SpringCloud依赖项目的版本依赖-->
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin><!-- SpringBoot 项目打jar包的Maven插件 -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

2.application.yml 修改

server:
  port: 8003

spring:
  application:
    name: cloud-provider #服务注册到Eureka上使用的名称

eureka:
  client:
    service-url:  # 集群情况下如下,如果是单机版,只需要配置单机版Eureka地址
      defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/
  instance:
    instance-id: cloud-provider-8003-hystrix
    prefer-ip-address: true #访问路径显示IP地址

info:   # 在Eureka上点击服务时会跳转到个404页面,可配置这里让他跳转到服务简介的一个页面,信息如下配置
  app.name: wuzz
  company.name: www.wuzz.com
  build.artifactId: server-provider
  build.version: 1.0

3. 修改Controller 接口 ,添加注解 @HystrixCommand

@RestController
public class TestController {

    @Autowired//服务发现
    private DiscoveryClient client;

    @GetMapping("/hello")
    @HystrixCommand(fallbackMethod = "processHystrix_Get")//熔断机制
    public String helloEureka(Long id) {
        if (id == null) {
            throw new RuntimeException();
        }
        return "Hello Eureka Provider1";
    }
    public String processHystrix_Get(Long id) {
        return "hello Hystrix";
    }
    /**
     * 服务发现
     *
     * @return
     */
    @RequestMapping(value = "/discovery", method = RequestMethod.GET)
    public Object discovery() {
        List<String> list = client.getServices();
        List<ServiceInstance> instances = client.getInstances("");
        for (ServiceInstance instance : instances) {
            System.out.println(instance.getHost());
        }
        return this.client;
    }
}

4.修改主启动类

@EnableEurekaClient //eureka客户端
@SpringBootApplication // boot启动类
@EnableDiscoveryClient // 提供服务发现
@EnableCircuitBreaker // 对Hystrix熔断机制的支持
public class EurekaServerProviderApp {
    private final static Logger log = LoggerFactory.getLogger(EurekaServerProviderApp.class);

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerProviderApp.class,args);
        log.info("服务启动成功");

    }
}

  这样就配置好了服务熔断,当某个接口发生异常时,就会跳转进配置的方法。

服务降级:

  整体资源快不够了,忍痛将某些服务先关掉,待渡过难关,再开起会来。所谓降级,一般是从整体负荷考虑,就是当某个服务熔断后,服务器将不再被调用,此时客户端可以准备自己本地的一个fallback回调,返回一个缺省值,这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强,服务降级是在客户端进行的.

  1. 根据目标接口,创建一个实现了FallbackFactory的类 

@Component
public class HystrixClientService implements FallbackFactory<ClientService> {
    @Override
    public ClientService create(Throwable throwable) {
        return new ClientService() {
            @Override
            public String hello() {
                return "服务降级。。。。";
            }
        };
    }
}

  2.在目标接口上的@FeignClient中添加fallbackFactory属性值

@FeignClient(value ="cloud-provider", fallbackFactory = HystrixClientService.class)
public interface ClientService {

    @RequestMapping(value ="/hello",method= RequestMethod.GET)
    String hello() ;
}

  3.修改 application.yml ,添加一下

feign: 
   hystrix: 
    enabled: true

  这样就完成了服务降级的基本配置,可以进入测试。。。。

猜你喜欢

转载自www.cnblogs.com/wuzhenzhao/p/9473073.html