Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等;Hystrix能够保证在一个依赖处问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性;
"断路器" 本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方向返回一个符合预期的、可处理的备选响应(fallback),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要的占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩;
使用feign做服务调用时,provider和consumer需要依赖相同的service服务
org.springframework.cloud
spring-cloud-starter-netflix-hystrix
org.springframework.cloud
spring-cloud-starter-openfeign
feign中默认是关闭对Hystrix的支持的,我们需要放开设置
server:
port: 9001
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
#设置feign客户端超时时间(openFeign默认支持Ribbon)
ribbon:
# 配置建立连接所用时间,使用与网络状态正常的情况下,两端连接所用的时间
ReadTimeout: 5000
# 配置连接后从服务器读取到可用资源所用的时间
ConnectTimeout: 5000
#手动打开feign对hystrix的支持
feign:
hystrix:
enabled: true
@SpringBootApplication
@EnableFeignClients
@EnableHystrix
public class Order9001Hystrix {
public static void main(String[] args) {
SpringApplication.run(Order9001Hystrix.class,args);
}
}
业务层接口中我们不需要再继承自service中的父接口了,直接在接口中声明一模一样的方法接口
@Component
@FeignClient(value = "CLOUD-HYSTRIX-PAYMENT8010",fallback = PaymentFallbackHysyrixService.class)
public interface PaymentHystrixService {
@GetMapping("/payment/hystrix/ok/{id}")
String paymentInfo_Ok(@PathVariable("id") Integer id);
@GetMapping("/payment/hystrix/timeout/{id}")
String paymentInfo_TimeOut(@PathVariable("id") Integer id);
}
添加返回兜底数据的类
@Component
public class PaymentFallbackHysyrixService implements PaymentHystrixService {
@Override
public String paymentInfo_Ok(Integer id) {
return "PaymentFallbackHysyrixService=> paymentInfo_Ok ==>fallback==>id="+id;
}
@Override
public String paymentInfo_TimeOut(Integer id) {
return "PaymentFallbackHysyrixService=> paymentInfo_TimeOut ==>fallback==>id="+id;
}
}
控制层
//@DefaultProperties(defaultFallback = "paymentInfo_gloBalHandler")
public class OrderHystrixController {
@Resource
private PaymentHystrixService paymentHystrixService;
@GetMapping("/consumer/payment/hystrix/ok/{id}")
public String paymentInfo_Ok(@PathVariable("id") Integer id) {
String result = paymentHystrixService.paymentInfo_Ok(id);
return result;
};
@GetMapping("/consumer/payment/hystrix/timeout/{id}")
// @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
// @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")//3秒以内为正常业务逻辑
// })
// @HystrixCommand
public String paymentInfo_TimeOut(@PathVariable("id") Integer id) {
String result = paymentHystrixService.paymentInfo_TimeOut(id);
return result;
};
public String paymentInfo_TimeOutHandler(Integer id) {
return "我是消费者,对方支付系统繁忙请稍后重试!!!!!!";
}
public String paymentInfo_gloBalHandler() {
return "我是消费者,global全局降级服务!!!!!!";
}
}
业务处理类
@Service
public class PaymentServiceImpl implements PaymentService {
@Override
public String paymentInfo_Ok(Integer id) {
return "线程池" + Thread.currentThread().getName()+" paymentInfo_Ok id=>"+id + "正确";
}
@Override
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")//5秒以内为正常业务逻辑
})
public String paymentInfo_TimeOut(Integer id) {
int timeNumber = 3;
try {
TimeUnit.SECONDS.sleep(timeNumber);
}catch (Exception e){
e.printStackTrace();
}
return "线程池" + Thread.currentThread().getName()+" paymentInfo_Ok id=>"+id + "超时 =>" +timeNumber ;
}
public String paymentInfo_TimeOutHandler(Integer id) {
return "线程池" + Thread.currentThread().getName()+" 8001系统繁忙请稍后重试!!! id=>"+id + " 放心有我在兜底!!";
}
}
控制层
@RestController
@Slf4j
public class PaymentController {
@Resource
private PaymentService paymentService;
@Value("${server.port}")
private String serverPort;
@GetMapping("/payment/hystrix/ok/{id}")
public String paymentInfo_Ok(@PathVariable("id") Integer id) {
String result = paymentService.paymentInfo_Ok(id);
log.info("*****result===>"+result);
return result;
}
@GetMapping("/payment/hystrix/timeout/{id}")
public String paymentInfo_TimeOut(@PathVariable("id") Integer id) {
String result = paymentService.paymentInfo_TimeOut(id);
log.info("*****result===>"+result);
return result;
}
}
在服务的提供者主启动类中添加注解
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class PaymentHystrix8010 {
public static void main(String[] args) {
SpringApplication.run(PaymentHystrix8010.class,args);
}
}
正常访问
修改业务PaymentServiceImpl
@Service
public class PaymentServiceImpl implements PaymentService {
@Override
public String paymentInfo_Ok(Integer id) {
return "线程池" + Thread.currentThread().getName()+" paymentInfo_Ok id=>"+id + "正确";
}
@Override
@HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")//3秒以内为正常业务逻辑
})
public String paymentInfo_TimeOut(Integer id) {
int timeNumber = 5;
try {
TimeUnit.SECONDS.sleep(timeNumber);
}catch (Exception e){
e.printStackTrace();
}
return "线程池" + Thread.currentThread().getName()+" paymentInfo_Ok id=>"+id + "超时 =>" +timeNumber ;
}
public String paymentInfo_TimeOutHandler(Integer id) {
return "线程池" + Thread.currentThread().getName()+" 8001系统繁忙请稍后重试!!! id=>"+id + " 放心有我在兜底!!";
}
}
降级后的访问