文章目录
前言
Hystri链路熔断,主要是做服务的熔断(不是降级)。当消费端调用某个服务时,被调用服务无法避免出现异常,例如查找的数据不存在,发生运行时异常等。这是被调用方需要返回一个合理的值,不能让调用方处于等待状态。个人感觉就和全局异常处理器,aop的环绕通知的异常通知之类的类似,只不过上升到服务级别。
1.服务提供方加入Hystrix相关依赖
<!--hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
2.服务提供方主启动类开启Hystrix,加注解@EnableCircuitBreaker
@SpringBootApplication
@EnableEurekaClient
/*hystrix启用注解*/
@EnableCircuitBreaker
public class ProviderHystrixMain_8001 {
public static void main(String[] args) {
SpringApplication.run(ProviderHystrixMain_8001.class,args);
}
}
3.在需要处理异常的controller方法上加Hystix注解指定处理异常的方法 @HystrixCommand
@RestController
public class DeptController {
@RequestMapping(value = "deptWithId/{id}", method = RequestMethod.GET)
@HystrixCommand(fallbackMethod = "findOneHystrix")
public Dept findOne(@PathVariable("id") Long id) {
if (id > 10) {
throw new RuntimeException("cant find data");
}
return new Dept(UUID.randomUUID().toString(), "研发部", "db12");
}
//异常处理的方法,当发生运行时异常时,hystrix会自动调用
public Dept findOneHystrix(@PathVariable("id") Long id) {
// public Dept findOneHystrix() {
return new Dept().setDeptName("noData");
}
}
在上面要注意的一个地方是 @HystrixCommand(fallbackMethod = “findOneHystrix”)中的方法findOneHystrix参数必须和原方法一样,不然调用接口会出现类似下面截图的异常
完善
对于hystrix以上的使用方法时存在一些问题的,例如,当服务提供方挂掉时,服务调用方是得不到返回值的因为异常等处理的逻辑都是放在了服务提供方;还有在服务提供方中异常处理的方法和业务逻辑本身是高度耦合的是不合理的。所以使用hystrix的另外一种使用方法,在api的工程中针对每一个Service来分装处理异常的逻辑,这样即使是服务提供方挂掉了,服务调用方一样会得到返回值,并且业务逻辑和异常处理是分离开来的。
1.在api工程中添加FallbackFactory的实现类
/*
* 处理DeptService服务调用发生异常时的hystrix
* */
@Component//这个注解不能去掉
public class DeptServiceFallbackFactory implements FallbackFactory<DeptService> {
@Override
public DeptService create(Throwable throwable) {
return new DeptService() {
@Override
public Dept findOne(Long id) {
return new Dept().setDeptName("no data in db");
}
@Override
public Dept add(Dept dept) {
return null;
}
@Override
public Dept update(Dept dept) {
return null;
}
@Override
public Dept delete(Long id) {
return null;
}
};
}
}
以上类是做异常处理用的
2.在api工程对应的Service中@@FeignClient添加fallbackFactory属性
/*
* 定义访问注册中心的接口
* */
@FeignClient(value = "DEPT-PROVIDER",fallbackFactory = DeptServiceFallbackFactory.class)
public interface DeptService {
@RequestMapping(method = RequestMethod.GET, path = "dept/{id}")
Dept findOne(@PathVariable("id")Long id);
@RequestMapping(method = RequestMethod.POST, path = "dept")
Dept add(@RequestBody Dept dept);
@RequestMapping(method = RequestMethod.PUT, path = "dept")
Dept update(@RequestBody Dept dept);
@RequestMapping(method = RequestMethod.DELETE, path = "dept")
Dept delete(Long id);
}
3.重新打包api工程!
这一步是个坑,当时我就是没有打包,导致代码一直没有更新,调试结果不尽人意没有出现预期结果。
4.在消费端的yml文件中开启hystrix
有自己在主启动类上添加@EnableHystrix,但是不好使
feign:
hystrix:
enabled: true
5.测试
启动服务提供方,消费方,eureka 先得到正常的接口访问,然后将服务提供方停止,再调用接口就能得到在api工程中定义的返回结果。