SpringCloud Feign能够进行服务消费,并且内置了Hystrix,可以进行熔断。
Feign能够经过fallback指定熔断回调的类。代码示例及讲解可见:
https://www.cnblogs.com/expiator/p/10826852.html
可是,有时候咱们还须要记录异常信息,能够经过fallbackFactory实现。html
示例以下:java
@RestController public class UserController { @PostMapping("/user/name/{id}") public JSONObject getUserNameById(@PathVariable("id") Integer id ) throws Exception { System.out.println("==================================================================>getUserNameById(),id为:"+id); //直接抛异常,是为了方便测试服务熔断和降级。 throw new Exception("getUserNameByIdException"); } @PostMapping("/user") public User getUserById(@RequestParam("id") Integer id ) throws Exception { System.out.println("==================================================================>getUserById(),id为:"+id); throw new Exception("getUserByIdException"); } }
首先是@FeignClient,属性fallbackFactory指定实现类,以下:git
/** * 使用fallbackFactory捕获异常,并进行服务熔断、服务降级。 */ @FeignClient(value = "eureka-client",fallbackFactory = UserFeignClientFallbackFactory.class) public interface UserFeignClient { @PostMapping(value = "/user/name/{id}") JSONObject getUserNameById(@PathVariable("id") Integer id); @PostMapping(value = "/user") User getUserById(@RequestParam("id") Integer id); }
接下来是FallbackFactory的实现类,须要重写create()方法,这个方法的参数为Throwable异常类,能够借此记录异常信息。
create()返回进行服务熔断/降级的Hystrix类。github
@Component public class UserFeignClientFallbackFactory implements FallbackFactory<UserFeignClient> { @Override public UserFeignClient create(Throwable cause) { System.out.println("====================================》fallback reason was: " + cause.getMessage()); return new UserFeignClientHystrix(); //也能够不写UserClientFallbackFactory类,直接用匿名对象写成如下形式: // return new UserFeignClient(Integer id) { // @Override // public JSONObject getUserNameById() { // JSONObject resultJson = new JSONObject(); // resultJson.put("id", "-1" ); // resultJson.put("name", "null" ); // return resultJson; // } // }; } }
Hystrix类以下所示:app
@Component public class UserFeignClientHystrix implements UserFeignClient { /** * 服务熔断 * @param id * @return */ @Override public JSONObject getUserNameById(Integer id) { System.out.println("=======================>UserFeignClientHystrix "); JSONObject resultJson = new JSONObject(); resultJson.put("errCode", "0404" ); String description="查询id为"+id+"的用户,服务异常,暂时熔断"; resultJson.put("description", description ); return resultJson; } @Override public User getUserById(Integer id) { System.out.println("=======================>UserFeignClientHystrix "); //直接返回id为-1的用户 User user = new User(); user.setId(-1); return user; } }
启动注册中心,服务提供者,服务消费者。
访问服务消费者的接口,就可以获得服务提供者抛出的熔断结果和异常信息。
访问getUserById对应的接口,结果以下:
ide
访问另外一个接口,返回结果以下:
异常信息以下所示:测试
====================================》fallback reason was: {} status 500 reading UserFeignClient#getUserNameById(Integer); content: {"timestamp":1557456567128,"status":500,"error":"Internal Server Error","exception":"java.lang.Exception","message":"getUserNameByIdException","path":"/user/name/2"} =======================>UserFeignClientHystrix
能够看到message中的异常getUserNameByIdException,就是咱们在服务提供者中抛出的异常。firefox
https://github.com/firefoxer1992/SpringCloudProject/tree/master/eureka-consumer-feign/src/main/java/com/example/democode