第四篇:熔断器Hystrix(断路器)

在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用,在SpringCloud中用Rest+Ribbon或Feign来调用。
由于网络原因或者自身的原因,服务并不能保证100%可用,如果某个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“**雪崩**”效应。

 

Hystrix(断路器)的作用是什么
当对特定的服务的调用的不可用达到一个阀值(Hystric 是5秒20次) 断路器将会被打开。断路打开后,可用避免连锁故障,fallback方法可以直接返回一个固定值。

本篇基上一篇的项目

Ribbon使用断路由

开始改造service-ribbon
在pox.xml文件中加入spring-cloud-starter-netflix-hystrix的依赖

<!--Eureka依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--Web依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--Ribbon依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

        <!--断路器(Hystrix)依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

在启动类加上@EnableHystrix,开启Hystrix

package com.niuben;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

/**
 * Author: NiuBen
 * Date: Created in 2020/3/3 17:17
 * Description:
 */
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
public class ServiceRibbonHystrixApplication {

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

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

}

改造HelloService类,在hiService方法上加上@HystrixCommand注解。该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法,熔断方法直接返回了一个字符串,字符串为"hi,"+name+",sorry,error!"

@Service
public class HelloService {

    @Autowired
    RestTemplate restTemplate;

    // @HystrixCommand:该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法
    @HystrixCommand(fallbackMethod = "hiError")
    public String hiService(String name) {
        return restTemplate.getForObject("http://eureka-client/hi?name=" + name, String.class);
    }

    public String hiError(String name) {
        return "hi," + name + ",sorry,error!";
    }

}

依次启动eureka-server,service-client,service-ribbon,访问http://localhost:8764/hi?name=haha,显示

hi haha ,现在的端口是:8762

此时关闭service-client,在访问http://localhost:8764/hi?name=haha,显示

hi ,forezp,orry,error!

说明当 service-client 工程不可用的时候,service-ribbon调用eureka-client的API接口时,会执行快速失败,而不是等待响应超时,这很好的控制了容器的线程阻塞

Feign使用断路由

Feign是自带断路器的,在D版本的SpringCloud之后,它没有默认打开。需要在配置文件中配置打开它

feign.hystrix.enabled=true

使用上一篇工程

复制service-feign工程,给名为service-feign-hystrix,只需要在FeignClient的SchedualServiceHi接口的注解中加上fallback的指定类,

@FeignClient(value = "eureka-client", fallback = SchedualServiceHiHystric.class)
public interface ServiceFeignTest {

    @RequestMapping(value = "/hi", method = RequestMethod.GET)
    String sayHiFromClientOne(@RequestParam(value = "name") String name);

}

其中SchedualServiceHiHystric需要实现SchedualServiceHi 接口,并注入到Ioc容器中

@Component
public class SchedualServiceHiHystric implements ServiceFeignTest {

    @Override
    public String sayHiFromClientOne(String name) {
        return "sorry " + name;
    }
}

依次启动eureka-server,service-client,service-feign,访问http://localhost:8765/hi?name=haha,显示

hi haha ,现在的端口是:8762

此时关闭service-client,在访问http://localhost:8765/hi?name=haha,显示

hi ,forezp,orry,error!

证明断路器起到作用了。

 

源码:https://gitee.com/niugit_admin/spring-cloud-finchley

posted @ 2020-03-07 14:24  如何下笔呢  阅读(355)  评论(0编辑  收藏  举报
levels of contents