04. Hystrix
04. Hystrix
#一个方法对应一个@HystrixCommand
在Feign的基础上修改, 添加一个新模块, 复制拷贝服务提供者
-
pom.xml
添加依赖, 值得注意的是@EnableHystrix不再该依赖中, 而是在eureka-client中
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
- controller
@RestController
@RequestMapping("/provider")
public class DeptProviderController {
@Autowired
private DeptService deptService;
@GetMapping(path = "get/{id}")
//类似于aop的@Throwing
//标明改方法是否有熔断机制,fallback方法必须定义在和@HystrixCommand同一个类下
@HystrixCommand(fallbackMethod = "get_Error1")
public Dept get(@PathVariable("id") Integer id) {
Dept dept = deptService.get(id);
System.out.println(dept);
if (ObjectUtils.isEmpty(dept)) {
throw new RuntimeException();
}
return deptService.get(id);
}
//必须保证fallbackMethod方法的参数返回类型要与原方法一致
//同样能使用@HystrixCommand
@ResponseBody
public Dept get_Error1(Integer id) {
return new Dept().setDName("id 不用存在");
}
}
- 主启动类
//特指开启hystrix, 也可以使用@EnableCircuitBreaker
@EnableHystrix
//@EnableCircuitBreaker
@EnableEurekaClient//表明,本服务启动后会自动注入eureka服务中
@SpringBootApplication
public class MicrosoftProviderHystrix8001Application {
public static void main(String[] args) {
SpringApplication.run(MicrosoftProviderHystrix8001Application.class, args);
}
}
#FallbackFactory 实现解耦
这里无需在api中加入hystrix依赖
FabllbackFactory在feign->hystrix 包下
- 修改api 模块
/**
* 如果DeptClientService调用方法时出错,FallbackFactory将被激活
* 对DeptClientService统一服务降级
* 不用再配置一个方法一个@HystrixCommand, 解耦
*/
//添加注解以便被服务者微服务扫描到
@Component
public class DeptClientFallbackFactory implements FallbackFactory<DeptClientService> {
//统一处理服务降级
@Override
public DeptClientService create(Throwable cause) {
return new DeptClientService() {
@Override
public boolean add(Dept dept) {
return false;
}
@Override
public Dept get(Integer id) {
return new Dept().setDName("fallback factory 用户不存在");
}
@Override
public List<Dept> list() {
return null;
}
};
}
}
- yml添加如下内容
feign:
hystrix:
enabled: true
- 修改消费服务模块, 主启动类
@EnableFeignClients(basePackages = {"com.chz.microsoftapi.service"})
@EnableEurekaClient
//如果调用的组件在其他模块中,要扫描组件所在的包并加入到当前模块中的ioc
//由于scanBasePackage会覆盖原有的扫描范围,所以要加上本模块要扫描的包
@SpringBootApplication(scanBasePackages = {"com.chz.microsoftapi.service",
"com.chz.microsoftconsumer80feign.controller"})
public class MicrosoftConsumer80FeignApplication {
public static void main(String[] args) {
SpringApplication.run(MicrosoftConsumer80FeignApplication.class, args);
}
}