FallbackFactory使用

概述

在FeignClient中,可以通过制定fallback,实现在服务不可用时自动调用fallback指定定的处理方法。
启动类

@EnableDiscoveryClient
@EnableFeignClients
@EnableFeignInterceptor
@SpringBootApplication
public class FileCenterApp {
    public static void main(String[] args) {
        SpringApplication.run(FileCenterApp.class, args);
    }
}

接口类,绑定FallbackFactory类

@FeignClient(name = "file-center", fallbackFactory = FileServiceFallbackFactory.class, decode404 = true)
public interface FileService {
    @GetMapping(value = "/files", params = "ids")
    List<FileInfo> findFiles(@RequestParam("ids") List<String> ids);
}

只需要加入decode404 = true这一个参数,Feign对于2XX和404 ,都不会走Fallback。
排除404,已经基本上够用,如果想把409、400等status也加到例外中,可以重写一下Feign的errorDecoder。

@Slf4j
public class FileServiceFallbackFactory implements FallbackFactory<FileService> {
    @Override
    public FileService create(Throwable throwable) {
        return new FileService() {
            @Override
            public List<FileInfo> findFiles(List<String> ids) {
                log.error("获取文件信息异常:{}", ids, throwable);
                return new ArrayList<>();
            }
        };
    }
}

对应的contractor代码:

// 服务降级:若当前处理器方法发生异常,则执行fallbackMethod属性指定的方法
@HystrixCommand(fallbackMethod = "findFilesDefault")
@GetMapping("/files")
public List<FileInfo> findFiles(@RequestParam List<String> ids) {
    return fileService.findList(ids);
}

/**
 * 记得@PathVariable一定要设置括号里面的value,否则报错PathVariable annotation was empty on param 0.
 */
@GetMapping("/download/{fileName}")
String downloadFile(@PathVariable("fileName") String fileName);

public List<FileInfo> findFilesDefault(@RequestParam List<String> ids) {
    return fileService.findList(ids);
}

上面配置两种服务降级形式,一种是类级别的FallbackFactory,一种是方法级别的FallbackMethod,FallbackFactory优先级高于FallbackMethod,即同时存在时不会走FallbackMethod。

fallback & fallbackFactory

/**
 * Fallback class for the specified Feign client interface. The fallback class must implement the interface annotated by this annotation and be a valid spring bean.
 */
Class<?> fallback() default void.class;

/**
 * Define a fallback factory for the specified Feign client interface. The fallback factory must produce instances of fallback classes that implement the interface annotated by {@link FeignClient}. The fallback factory must be a valid spring bean.
 * @see feign.hystrix.FallbackFactory for details.
 */
Class<?> fallbackFactory() default void.class;

使用示例:

@FeignClient(value = "merchant-provider", fallback = RemoteMerchantServiceFallbackImpl.class,
fallbackFactory = RemoteMerchantServiceFallbackFactory.class)
public interface RemoteMerchantService {
    @RequestMapping(value = {"/merchant/app/findByAppKey"}, method = {RequestMethod.POST})
    Response<GetMerchantAppVO> findByAppKey(GetMerchantAppInfoDTO merchantAppInfoDTO);
}
@Slf4j
@Component
public class RemoteMerchantServiceFallbackImpl implements RemoteMerchantService {
    @Override
    public Response<GetMerchantAppVO> findByAppKey(GetMerchantAppInfoDTO merchantAppInfoDTO) {
        log.info("Fallback findByAppKey...");
        return Response.error();
    }
}
import feign.hystrix.FallbackFactory;

@Component
public class RemoteMerchantServiceFallbackFactory implements FallbackFactory<RemoteMerchantService> {
	@Override
    public RemoteMerchantService create(Throwable throwable) {
        log.error("异常原因: ", throwable);
        return new RemoteMerchantService() {
            @Override
            public Response<GetMerchantAppVO> findByAppKey(GetMerchantAppInfoDTO merchantAppInfoDTO) {
                log.info("Fallback findByAppKey...");
                return Response.error();
            }
        };
    }
}

两者有何区别呢?参考:https://arnoldgalovics.com/feign-fallback/

What’s the difference between this and the regular fallback? With the regular fallback, you can’t access the underlying exception that triggered the fallback however with the fallback factory, you can.

大致意思:

  • fallbackFactory:可以捕获异常信息即Throwable并打印,可返回默认降级结果。类似于断容器
  • fallback:不能捕获异常打印堆栈信息,不利于问题排查,可返回默认降级结果

TODO:不能同时使用?

参考

Hystrix FallbackFactory服务降级

posted @ 2021-06-27 11:27  johnny233  阅读(181)  评论(0编辑  收藏  举报  来源