天天看点

springboot集成hystrix和feign,解决fallback,fallbackFactory不生效问题

fallback,fallbackFactory不生效问题

以往我们配置在yml中配置如下,如果不生效可以改成下面配置:

注释掉feign.hystrix.enabled启用feign.circuitBreaker.enabled

#开启熔断
feign:
#  httpclient:
#    enabled: true
  client:
    config:
      metaDataClient:
        connect-timeout: 10000
        read-timeout: 10000
#  hystrix:
#    enabled: true
  circuitBreaker:
    enabled: true
           

feign调用无法解析IPage问题

该问题解决方法见链接:解决IPage无法解析问题

引入依赖

<!--feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        
        <!--hystrix-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>
           

启动类配置:

hystrix注解@EnableHystrix,feign注解@EnableFeignClients

@EnableFeignClients
@EnableHystrix
           

hystrix

该示例中提供了两种方法,一种是配置在controller上面,使用@DefaultProperties注解,一种是配置在方法上面使用@HystrixCommand注解,两种方法需要注意的地方是,生效的方法需要和原方法的参数一致,即参数个数,类型顺序一致;该示例中提供了两个defaultTest方法,最后打印输出的是"传入参数为:" + name + “方法异常”

@RestController
@RequestMapping("/blogLike")
@Api(tags = "BlogLikeController", description = "博客点赞Controller")
//@DefaultProperties(defaultFallback = "defaultTest")
public class BlogLikeController {

    @Resource
    private IBlogLikeService iBlogLikeService;

    @Resource
    private BlogFeign blogFeign;

    @PostMapping("/page")
    @ApiOperation(value = "分页查询")
    public IPage<BlogLike> page(@RequestBody BasePage page) {
        return iBlogLikeService.page(page);
    }

    @GetMapping("/test")
    @HystrixCommand(fallbackMethod = "defaultTest", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "310")
    })
    @ApiOperation("测试HystrixCommand")
    public String test(@RequestParam String name) {
        try {
            Thread.sleep(500L);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return blogFeign.test();
    }

    public String defaultTest(String name) {
        return "传入参数为:" + name + "方法异常";
    }

    public String defaultTest() {
        return "方法异常";
    }

    @GetMapping("/test2")
    @ApiOperation("测试fallback")
    public String test2() {
        return blogFeign.test();
    }


    @PostMapping("/page2")
    @ApiOperation(value = "分页查询2")
    public IPage<ResponseBlog> page2(@RequestBody BasePage page) {
        return blogFeign.page(page);
    }

    @GetMapping("/getById2")
    @ApiOperation(value = "根据id查询")
    public ResponseBlog getById2(@RequestParam Long id) {
        return blogFeign.getById(id);
    }
}
           

fegin

@FeignClient中属性name和value作用是一样的,对应的是spring.application.name这个属性(如果url没有配置的话,配置了单纯就是个名字),如果以name方式配置,则需要配合path使用,添加对应的请求路径前缀,当fallback和fallbackFactory同时配置时,生效的为fallback

@FeignClient(name = "producer-test",
//        path = "/producer/test/blog",
        url = "http://127.0.0.1:1003/producer/test/blog",
//        configuration = FeignConfig.class,
        fallback = BlogFallback.class,
        fallbackFactory = BlogFallbackFactory.class)
public interface BlogFeign {

    @PostMapping("/page")
    IPage<ResponseBlog> page(BasePage page);

    @GetMapping("/test")
    String test();

    @GetMapping("/getById")
    ResponseBlog getById(Long id);
}

           

fallback对应实现类

@Component
@Slf4j
public class BlogFallback implements BlogFeign {


    @Override
    public IPage<ResponseBlog> page(BasePage page) {
        return null;
    }

    @Override
    public String test() {
        return "fallback-test方法错误";
    }

    @Override
    public ResponseBlog getById(Long id) {
        return null;
    }


}
           

fallbackFactory对应实现类

@Component
@Slf4j
public class BlogFallbackFactory implements FallbackFactory<BlogFeign> {

    @Override
    public BlogFeign create(Throwable cause) {
        log.error("feign服务异常,错误信息如下:" + cause.getMessage());

        return new BlogFeign() {
            @Override
            public IPage<ResponseBlog> page(BasePage page) {
                return null;
            }

            @Override
            public String test() {
                return "fallbackFactory-test方法错误";
            }

            @Override
            public ResponseBlog getById(Long id) {
                return null;
            }
        };
    }
}