Spring Cloud(四)断路器(Hystrix)

一、Hystrix简介

在微服务架构中,我们将系统拆分成了一个个的服务单元,各单元间通过服务注册与订阅的方式互相依赖。由于每个单元都在不同的进程中运行,依赖通过远程调用的方式执行,这样就有可能因为网络原因或是依赖服务自身问题出现调用故障或延迟,而这些问题会直接导致调用方的对外服务也出现延迟,若此时调用方的请求不断增加,最后就会出现因等待出现故障的依赖方响应而形成任务积压,最终导致自身服务的瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。
断路器(Circuit Breaker)模式: 为了解决上述问题,因此产生了断路器模式。

断路器本身是一种开关装置,用于在电路上保护线路过载,当线路中有电器发生短路时,“断路器”能够及时的切断故障电路,防止发生过载、发热、甚至起火等严重后果。

在分布式架构中,断路器模式的作用也是类似的,当某个服务单元发生故障(类似用电器发生短路)之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个错误响应,而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放,避免了故障在分布式系统中的蔓延。在Spring Cloud中使用了Hystrix 来实现断路器的功能。接着我们使用前面创建的项目分别在服务消费断Ribbn与Feign中使用断路由模式:

参考概念:
https://projects.spring.io/spring-cloud/spring-cloud.html#_spring_cloud_netflix
https://cloud.spring.io/spring-cloud-netflix/

二、在Ribbon中集成Hystrix断路由

2.1 pom中增加Hystrix依赖

改造上节中ribbon-consumer 工程的代码,首先在pox.xml文件中加入spring-cloud-starter-netflix-hystrix的起步依赖:

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2.2 加@EnableHystrix注解

在springboot启动类中 加@EnableHystrix注解开启Hystrix:

@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
public class RibbonConsumerApplication {

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

	@Bean
	@LoadBalanced
	RestTemplate restTemplate() {
		return new RestTemplate();
	}
}
2.3 改造HelloService类

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

@Service
public class HelloService {

    @Autowired
    RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "hiError")
    public String hiService(String name) {
        return restTemplate.getForObject("http://eureka-client/hello",String.class);
    }
    //Fall Back method
    public String hiError(String name) {
        return "hi,"+name+",sorry,error!";
    }
}
2.4 验证结果

启动注册中心,启动ribbon-consumer,当我们访问http://localhost:8083/hi/payne,浏览器显示:
在这里插入图片描述
可以看到,当外部接口不能访问的时候,程序直接调用fallback指定的方法返回结果,从而不需要阻塞当前线程,从而导致访问请求一直处于等待
当启动eureka-client,再次访问的时候

hi ,i am from port:8081

三、Feign中使用断路器-fallback

3.1 Enable Hystrix

Feign是自带断路器的,因此不需要人为引用Hystrix依赖包,但是设置

feign.hystrix.enabled=true

注意:properties文件可能不自动提示feign.hystrix.enabled

3.2 FeignClient接口改造

基于feign-consumer工程进行改造,只需要在FeignClient的HelloService接口的注解中加上fallback的指定类就行了:

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

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

}
3.3 添加FallBack指定类

FallBackHelloService需要实现HelloService 接口,并注入到Ioc容器中,代码如下:

@Component
public class FallBackHelloService implements HelloService{

    @Override
    public String hiService() {
        return "Sorry,this is fall back method";
    }
}
3.4 验证结果

访问地址: http://localhost:8084/hi
在这里插入图片描述
打开eureka-client工程,再次访问,浏览器又返回正常结构,说明我们的断路由已经生效。

四、Feign中使用断路器-fallbackFactory

4.1 添加FallBackFactory指定类

FallBackFactory类需要实现FallbackFactory接口,传入泛型对应的service客户端,并覆盖对应方法,返回service客户端对象。

@Component
public class ClientFallBackFactory implements FallbackFactory<HelloService>{

    private static Logger LOGGER = LoggerFactory.getLogger(ClientFallBackFactory.class);
    @Override
    public HelloService create(Throwable throwable) {
        LOGGER.error("Fall Back Error,"+throwable.getMessage(),throwable);
        return new HelloService(){

            @Override
            public String hiService() {
                return "Sorry,this fall back from FallBackFactory";
            }
        };
    }
}
4.2 指定FallBackFactory

添加指定类fallbackFactory = ClientFallBackFactory.class

@FeignClient(value = "eureka-client",fallbackFactory = ClientFallBackFactory.class)
public interface HelloService {

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

}

验证之后 ,可以看到同样的效果

GitHub项目地址:https://github.com/PayneYu/spring-cloud-study

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值