参考文章:springcloud----服务熔断、降级、限流--之--Hystrix-服务降级
服务降级、服务熔断、服务限流、服务隔离
分布式面临的问题:
负责的分布式体系结构中应用程序有数十个依赖 ,可能会形成 调用链
(一个阻塞,全体等待) , 引起服务雪崩
Hystrix
是一个用于处理分布式系统的延迟和容错的开源库, 在分布式系统中,许多不可避免的调用会失败, 比如超时,一场等。Hystrix 能够保证在一个依赖出现问题的情况下,不会导致整体服务的失败、避免级联故障、以提高分布式系统的弹性。
“断路器
” 本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似保险熔断),向调用方返回一个符合预期的、可处理的备选响应(FallBack) 而不是时间的等待或抛出调用方法处理异常,这样就保证了服务调用方的线程不会长时间,不必要地占用
,从而避免了故障在分布式系统无线的蔓延,从而导致雪崩效应
。
重要概念
解决场景
- 服务超时(前台显示转圈)
- 出错(宕机或者程序运行出错)
解决
1.对方
服务超时
了,调用者不能一直死等,必须有服务降级
2. 对方
服务器down
机了,调用者不能卡死等待,必须有服务降级
3. 对方服务OK, 调用者
自己出现故障
(自己等待时间小于服务的超时时间,自己要求
服务降级)
服务端
1、模块名 cloud-provider-hystrix-payment8001
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
server:
port: 8001
spring:
application:
name: cloud-provider-hystrix-service
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker // 开启服务降级。 。。
public class PaymentHystrixMain8001 {
public static void main(String[] args){
SpringApplication.run(PaymentHystrixMain8001.class,args) ;
}
}
@Service
public class PaymentService {
/** 正常访问的*/
public String paymentInfoOk(Integer id){
return "线程池:"+Thread.currentThread().getName()+"paymentInfoOk"+id;
}
/** 服务降级的方法 */
@HystrixCommand(fallbackMethod ="paymentInfoTimeoutHandler",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")
})
public String paymentInfoTimeout(Integer id){
// int i = 10/0 程序出错 测试的时候自行打开
// 3秒内正常 超过3秒异常
try {
TimeUnit.SECONDS.sleep(3); // hutool 工具包中的方法
} catch (InterruptedException e) {
e.printStackTrace();
}
return "线程池:"+Thread.currentThread().getName()+"paymentInfoTimeout"+id;
}
// 服务降级 后 的callback方法
public String paymentInfoTimeoutHandler(Integer id){
return "调用失败,线程池:"+Thread.currentThread().getName()+"---paymentInfoTimeoutHandler"+id;
}
}
@RestController
public class PaymentController {
@Autowired
private PaymentService paymentService ;
@Value("${server.port}")
private String serverPort ;
// 正常方法
@GetMapping("/payment/hystrix/ok/{id}")
public String paymentInfoOk(@PathVariable("id") Integer id){
String s = paymentService.paymentInfoOk(id);
System.out.println("result"+s);
return s ;
}
// 超时 、报错。。
@GetMapping("/payment/hystrix/timeout/{id}")
public String paymentInfoTimeout(@PathVariable("id") Integer id){
String s = paymentService.paymentInfoTimeout(id);
System.out.println("result"+s);
return s ;
}
}
消费端
1、模块名 cloud-consumer-feign-hystrix-order80
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka
feign:
hystrix:
enabled: true
# 让feign支持 服务降级
ribbon:
ReadTimeout: 5000
ConnectTimeout: 6000
logging:
level:
# feign 日志以什么级别监控那个接口
com.aqiang9.springcloud.service.PaymentHystrixService: debug
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix // 服务降级
public class OrderHystrixMain80 {
public static void main(String[] args){
SpringApplication.run(OrderHystrixMain80.class,args) ;
}
}
@RestController
public class OrderHystrixController {
@Autowired
private PaymentHystrixService paymentHystrixService;
@GetMapping("/consumer/payment/hystrix/ok/{id}")
public String paymentInfoOk(@PathVariable("id") Integer id) {
return paymentHystrixService.paymentInfoOk(id);
}
@GetMapping("/consumer/payment/hystrix/timeout/{id}")
@HystrixCommand(fallbackMethod = "paymentInfoTimeoutFallbackMethod" , commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")
})
@HystrixCommand
public String paymentInfoTimeout(@PathVariable("id") Integer id) {
return paymentHystrixService.paymentInfoTimeout(id);
}
public String paymentInfoTimeoutFallbackMethod(@PathVariable("id") Integer id){
return "consumer 服务降级处理";
}
}
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-SERVICE",fallback = PaymentFallbackService.class)
public interface PaymentHystrixService {
@GetMapping("/payment/hystrix/ok/{id}")
String paymentInfoOk(@PathVariable("id") Integer id);
@GetMapping("/payment/hystrix/timeout/{id}")
String paymentInfoTimeout(@PathVariable("id") Integer id);
}
Hystrix 统一的全局配置
@DefaultProperties(defaultFallback = "globalFallbackMethod")
public class OrderHystrixController {
public String globalFallbackMethod(){
return "全局服务降级";
}
}
方式二 : 实现OpenFeign 的接口 并在接口
上进行指定
@Component
public class PaymentFallbackService implements PaymentHystrixService {
@Override
public String paymentInfoOk(Integer id) {
return "----PaymentFallbackService ---paymentInfoOk---fallback ";
}
@Override
public String paymentInfoTimeout(Integer id) {
return "----PaymentFallbackService ---paymentInfoTimeout --fallback ";
}
}
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-SERVICE",fallback = PaymentFallbackService.class)
public interface PaymentHystrixService {
@GetMapping("/payment/hystrix/ok/{id}")
String paymentInfoOk(@PathVariable("id") Integer id);
@GetMapping("/payment/hystrix/timeout/{id}")
String paymentInfoTimeout(@PathVariable("id") Integer id);
}