Spring Cloud微服务架构(七)断路器(Hystrix)
1、Hystrix简介
Hystrix是由Netflix创建一个类库。
在微服务的分布式环境中,系统存在许多服务依赖。在高并发访问下,这些依赖的稳定性与否对系统的影响非常大,但是依赖有很多不可控问题:如网络连接缓慢,资源繁忙,暂时不可用,服务脱机等。 Hystrix可以通过添加延迟容错和容错逻辑来帮助我们控制这些分布式服务之间的交互。 Hystrix通过隔离服务之间的接入点,阻止它们之间的级联故障,并提供备用选项,从而提高系统的整体弹性。
2、雪崩效应
在微服务架构中通常会有多个服务层调用,基础服务的故障可能会导致级联故障,进而造成整个系统不可用的情况,这种现象被称为服务雪崩效应。服务雪崩效应是一种因“服务提供者”的不可用导致“服务消费者”的不可用,并将不可用逐渐放大的过程。
如果下图所示:A作为服务提供者,B为A的服务消费者,C和D是B的服务消费者。A不可用引起了B的不可用,并将不可用像滚雪球一样放大到C和D时,雪崩效应就形成了。
3、在ribbon使用断路器
3.1、改造原有的springcloud-ribbon工程,在pox.xml文件中加入spring-cloud-starter-hystrix的断路器的依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.vesus</groupId> <artifactId>springcloud-ribbon-hystrix</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springcloud-ribbon-hystrix</name> <description>Demo project for Spring Boot</description> <parent> <groupId>com.vesus</groupId> <artifactId>springcloud-demo</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- eureka:微服务注册 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!--ribbon:负载均衡--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <!--开启断路器--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.2、在程序的启动类ServiceRibbonApplication 加@EnableHystrix注解开启Hystrix
package com.vesus.springcloudribbonhystrix; 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; @SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient @EnableHystrix public class SpringcloudRibbonHystrixApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudRibbonHystrixApplication.class, args); } @Bean @LoadBalanced // 添加负载均衡支持,很简单,只需要在RestTemplate上添加@LoadBalanced注解, // 那么RestTemplate即具有负载均衡的功能,如果不加@LoadBalanced注解的话, // 会报java.net.UnknownHostException异常,此时无法通过注册到Eureka Server上的服务名来调用服务, // 因为RestTemplate是无法从服务名映射到ip:port的,映射的功能是由LoadBalancerClient来实现的。 RestTemplate restTemplate(){ return new RestTemplate() ; } }
3.3、在HelloService方法上加上@HystrixCommand注解,开启熔断器。并指定了fallbackMethod熔断方法。
package com.vesus.springcloudribbonhystrix.service; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @Service public class HelloService { @Autowired RestTemplate restTemplate ; @HystrixCommand(fallbackMethod = "helloerror")//指定熔断方法 public String sayhello() { //SPRING-CLOUD-SERVICE为注册到Eureka Server上的应用名 return restTemplate.getForObject("http://SPRING-CLOUD-SERVICE/hello",String.class); } //熔断方法 public String helloerror(){ return "error" ; } }
3.4、启动:spirngcloud-ribbon-hystrix 工程,当我们访问http://localhost:8766/hello,浏览器显示:
hello world
3.5 关闭 springcloud-service 工程,当我们再访问http://localhost:8766/hello,浏览器会显示:
error
4、在fegin使用断路器
4.1、Feign是自带断路器的,它没有默认打开。需要在配置文件中配置打开它。
eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ # 注册中心地址 spring: application: name: spring-cloud-fegin-hystrix server: port: 8767 feign: hystrix: enabled: true
4.2、FeignClient的注解中加上fallback的指定类
package com.vesus.springcloudfeginhystrix.service; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; @FeignClient(value = "spring-cloud-service",fallback = HelloServiceError.class)//指定错误类 //springcloud-service中定义的服务的名字 public interface HelloService { @RequestMapping(value = "/hello") //springcloud-service中定义的服务方法 public String sayHello() ; }
4.3、增加fallback类,并实现HelloService方法。
package com.vesus.springcloudfeginhystrix.service; import org.springframework.stereotype.Component; @Component class HelloServiceError implements HelloService { @Override public String sayHello() { return "error"; } }
4.4、启动:spirngcloud-fegin-hystrix 工程,当我们访问http://localhost:8767/hello,浏览器显示:
hello world
4.5 关闭 springcloud-service 工程,当我们再访问http://localhost:8767/hello,浏览器会显示:
error