熔断
spring-cloud.s05.store-hystrix
在 pom
中添加依赖
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
添加配置文件
server: port: 31003 spring: application: name: store-hystrix eureka: client: serviceUrl: defaultZone: http://user:123123@localhost:34001/eureka/ instance: instance-id: ${spring.cloud.client.ip-address}:${server.port} prefer-ip-address: true lease-renewal-interval-in-seconds: 10 lease-expiration-duration-in-seconds: 30 info: app.name: ${spring.application.name} compony.name: me.xhy build.artifactId: $project.artifactId$ build.modelVersion: $project.modelVersion$
创建启动类 ..StoreHystrix
@SpringBootApplication @EnableEurekaClient // 开启降级 @EnableHystrix public class StoreHystrix { public static void main(String[] args) { SpringApplication.run(StoreHystrix.class, args); } @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } }
如果启动类中 不写
@EnableHystrix
注解,那么当方法失败时,是不会执行降级方法的;但是注解了 @HystrixCommand
的方法是可以有熔断功能的,默认值也依然是 3次
, 当失败次数达到3次时,在 ribbon 中剔除该资源。
创建程序访问入口 ..ConsumerCircuitController
@RestController @RequestMapping("/hystrix") public class CircuitFallbackController { @Autowired RestTemplate restTemplate; /* 新增了 @HystrixCommand @HystrixCommand(fallbackMethod = "getMoviesError") 默认键为 fallbackMethod 表示当调用 provider 失败,调用的补偿方法 默认情况下,发生3次错误(补偿方法调用了3次),该 provider 将被熔断 当被熔断的 provider 重新上线,将被重新加回到服务列表 */ @RequestMapping("/cf/ribbon") @HystrixCommand(fallbackMethod = "getServerPortError") public String getServerPort() { return restTemplate.getForObject("http://album-provider/album/server-port", String.class); } public String getServerPortError() { return "ribbon method getMovies occur hystrix"; } @RequestMapping("/cf/always-exception") @HystrixCommand(fallbackMethod = "getServerPortError") public String alwaysException() { if(true) throw new RuntimeException(); return "hi"; } }
这个 Controller 中有两个访问入口, @RequestMapping("/circuit/always-exception") 始终都会发生异常;@HystrixCommand(fallbackMethod = "getServerPortError") 则需要在正常访问所有 provider 后,停掉至少一个 provider 来观察结果。
验证熔断和降级
http://localhost:31003/hystrix/circuit/always-exception http://localhost:31003/hystrix/circuit/ribbon
启动类注解了 @EnableHystrix
服务降级才会生效。 @HystrixCommand
只有在应用 ribbon
的方法上,才会有熔断效果。
Feign 是自带断路器的,但是它没有默认打开。需要在配置文件中配置打开它
pom
中引入 Feign
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
在配置文件中打开断路器
feign: hystrix: enabled: true
启动类增加注解
@EnableFeignClients // Feign 需要
创建 Feign 接口
@FeignClient(value = "album-provider", fallback = CircuitFallbackFeignServiceFallback.class) public interface CircuitFallbackFeignService { @RequestMapping("/album/server-port") String getServerPort(); } /* 该类提供发生异常时的补偿方法 必须要有 @Component , 可以是外部类 */ @Component class CircuitFallbackFeignServiceFallback implements CircuitFallbackFeignService { @Override public String getServerPort() { return "feign method getServerPort occur hystrix"; } }
创建访问程序入口 ..CircuitFallbackFeignController
@RestController @RequestMapping("/hystrix") public class CircuitFallbackFeignController { @Autowired CircuitFallbackFeignService service; @RequestMapping("/cf/feign") public String getServerPort() { return service.getServerPort(); } }
访问 http://localhost:31003/hystrix/cf/feign
。
如果配置文件中不开启断路器,降级方法是不会执行的
隔离可以防止雪崩的出现。当 provider 没有足够的处理能力时, consumer 的请求无法返回导致线程挂起,逐层影响,最终雪崩。如果限制 consumer 请求某个 provider 的 量
, consumer 就不会因为 provider 丧失处理能力而挂起过多的线程, consumer 仍然可以保持服务能力,去做其他任务。