springcloud-基于feign的服务接口的统一hystrix降级处理

6次阅读

共计 3035 个字符,预计需要花费 8 分钟才能阅读完成。

springcloud 开发微服务时,基于 feign 来做声明式服务接口,当启用 hystrix 服务熔断降级时,项目服务众多,每个 Feign 服务接口都得写一些重复问的服务降级处理代码,势必显得枯燥无味:

Feign 服务接口:

@FeignClient(name="springcloud-nacos-producer", qualifier="productApiService", contextId="productApiService", fallback=ProductFallbackApiService.class)
public interface ProductApiService {

    /**
     * 创建商品
     * @param product
     */
    @PostMapping(value="/api/product/add", produces=APPLICATION_JSON, consumes=APPLICATION_JSON)
    public Result<Long> createProduct(@RequestBody Product product);
    
    /**
     * 修改商品
     * @param product
     */
    @PutMapping(value="/api/product/update", produces=APPLICATION_JSON, consumes=APPLICATION_JSON)
    public Result<Object> updateProduct(@RequestBody Product product);
    
    /**
     * 删除商品
     * @param productId
     */
    @DeleteMapping(value="/api/product/delete/{productId}", produces=APPLICATION_JSON)
    public Result<Object> deleteProductById(@PathVariable("productId") Long productId);
    
    /**
     * 根据 productId 获取商品信息
     * @param productId
     * @return
     */
    @GetMapping(value="/api/product/{productId}", produces=APPLICATION_JSON)
    public Result<Product> getProductById(@PathVariable("productId") Long productId);
    
    /**
     * 根据条件查询商品列表 (分页、排序)
     * @param condition
     * @param page
     * @param sort
     * @return
     */
    @GetMapping(value="/api/product/list1", produces=APPLICATION_JSON)
    public PageResult<List<Product>> getProductListByPage(@RequestParam Product condition, @RequestParam Page page, @RequestParam Sort sort);
}

对应的熔断降级处理类:

@Component
public class ProductFallbackApiService implements ProductApiService {

    private static final HttpStatus SERVICE_UNAVAILABLE = HttpStatus.SERVICE_UNAVAILABLE;
    
    protected <T> Result<T> defaultFallbackResult() {return Result.failure().code(String.valueOf(SERVICE_UNAVAILABLE.value())).message(String.format("请求失败:%s, %s", SERVICE_UNAVAILABLE.value(), SERVICE_UNAVAILABLE.getReasonPhrase())).build();}
    
    protected <T> PageResult<T> defaultFallbackPageResult() {return PageResult.failure().code(String.valueOf(SERVICE_UNAVAILABLE.value())).message(String.format("请求失败:%s, %s", SERVICE_UNAVAILABLE.value(), SERVICE_UNAVAILABLE.getReasonPhrase())).build();}
    
    @Override
    public Result<Long> createProduct(Product product) {return defaultFallbackResult();
    }

    @Override
    public Result<Object> updateProduct(Product product) {return defaultFallbackResult();
    }

    @Override
    public Result<Object> deleteProductById(Long productId) {return defaultFallbackResult();
    }

    @Override
    public Result<Product> getProductById(Long productId) {return defaultFallbackResult();
    }

    @Override
    public PageResult<List<Product>> getProductListByPage(Product condition, Page page, Sort sort) {return defaultFallbackPageResult();
    }

}

当服务较多时写这样重复的统一熔断降级处理显得十分枯燥无味!

前提场景是你的服务接口具有统一的报文格式,例如我的是 Result<T> 或者 PageResult<T>,这样才有统一全局处理的可能,否则每个服务的 fallback 你是省不了的

本文将采用 Cglib 动态代理来统一处理这些 fallback,说来容易做起来却十分棘手,完成这一功能,费了相当大的力气:

代码说明:
1、包 org.springframework.cloud.openfeign 中的都是为实现这一功能自定义的东西,至于包名为什么取 org.springframework.cloud.openfeign,那是因为 org.springframework.cloud.openfeign.Targeter 这个接口声明是 protected 的
2、上面 4 个类:DefaultFeignClientsConfiguration.java、DefaultHystrixFallbackHandler.java、DefaultHystrixFallbackHandlerFactory.java、HystrixFallbackResults.java 是在项目中具体使用的具体配置

代码位置:
1、https://github.com/penggle/xm…
2、https://github.com/penggle/xm…

快速上手入口:
https://github.com/penggle/xm…

正文完
 0