Hystrix服务降级
大致含义:服务器忙,请稍后再试,不让客户端等待并立刻返回一个友好提示,fallback。
哪些情况会出现服务降级
- 程序运行异常
- 超时
- 服务熔断触发服务降级
- 线程池/信号量打满也会导致服务降级
服务降级应该设置在服务端还是客户端
服务端与客户端均可设置服务降级,保证双方都达到服务降级,一般情况下,服务降级会设置于客户端。下文实现客户端与服务端均设置服务降级。
-
客户端与服务端均添加Hystrix依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>2.2.10.RELEASE</version> </dependency>
-
主启动类加上@EnableHystrix注解
@SpringBootApplication @EnableEurekaClient @MapperScan("com.example.demo.mapper") @EnableHystrix public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
-
服务端设置服务降级添加@HystrixCommand注解,并添加@HystrixProperty来配置服务降级的触发时机。
@Service public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements UsersService{ @Resource private UsersMapper usersMapper; /* @HystrixProperty设置规则,当login访问超3s或者程序报错时,服务降级调用loginHandler方法 */ @HystrixCommand(fallbackMethod = "loginHandler",commandProperties = { @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "3000") }) @Override public Result<Users> login(String username, String password) { //一系列业务逻辑 return result; } public Result<Users> loginHandler(String username, String password){ //当访问login失败,服务降级的一系列业务逻辑 return result; } }
-
客户端设置服务降级添加@HystrixCommand注解,并添加@HystrixProperty来配置服务降级的触发时机,由于服务端无feign要先添加properties配置。
feign.circuitbreaker.enabled=true
@RestController public class OrderController { @Resource private PaymentService paymentService; @Value("${server.port}") private Integer port; @GetMapping("/consumer/login/{username}/{password}") @HystrixCommand(fallbackMethod = "loginHandler",commandProperties = { @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "3000") }) public Result<Users> login(@PathVariable String username,@PathVariable String password){ return paymentService.login(username,password); } public Result<Users> loginHandler(@PathVariable String username,@PathVariable String password){ Result<Users> result = new Result<>(); result.setStatus(port); result.setMessage("登录超时/错误请稍后再试"); result.setData(null); return result; } }
-
另一种服务降级的方法(可降耦合),实现客户端的service接口重写方法,在@FeignClient注解加入fallback属性,当出现服务端程序错误、超时、宕机时会调用fallback属性指定的类。
@RestController public class OrderController { @Resource private PaymentService paymentService; @GetMapping("/consumer/login/{username}/{password}") public Result<Users> login(@PathVariable String username,@PathVariable String password){ return paymentService.login(username,password); } }
@Component @FeignClient(value = "CLOUD-PAYMENT-SERVICE",fallback = PaymentFallBackService.class) public interface PaymentService { @GetMapping("/sent/user/login/{username}/{password}") @LoadBalanced Result<Users> login(@PathVariable String username, @PathVariable String password); }
@Component public class PaymentFallBackService implements PaymentService{ @Override public Result<Users> login(String username, String password) { return null; } }
全局通用的服务降级DefaultProperties
添加@DefaultProperties(defaultFallback = “loginHandler”)指定通用的服务降级,当@HystrixCommand没有特别指定降级方法时就使用统一的降级服务。但返回类型必须一致?
@RestController
@DefaultProperties(defaultFallback = "loginHandler")
public class OrderController {
@Resource
private PaymentService paymentService;
@Value("${server.port}")
private Integer port;
@GetMapping("/consumer/login/{username}/{password}")
@HystrixCommand
public Result<Users> login(@PathVariable String username,@PathVariable String password){
return paymentService.login(username,password);
}
public Result<Users> loginHandler(@PathVariable String username,@PathVariable String password){
Result<Users> result = new Result<>();
result.setStatus(port);
result.setMessage("登录超时/错误请稍后再试");
result.setData(null);
return result;
}
}