熔断
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 仍然可以保持服务能力,去做其他任务。