天天看點

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;
            }
        };
    }
}