Spring Cloud Feign 及 Hystrix 回滚

引入依赖

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
</dependencies>

启动类:

@EnableFeignClients(basePackages = "club.cearnach")
@SpringCloudApplication
@ComponentScan(basePackages = "club.cearnach")
public class OrderServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServerApplication.class, args);
    }
}

 

声明一个Client , fallback指定要回滚的实现类.

@FeignClient(name = "PRODUCT-SERVER", fallback = ProductClient.ProductClientFallback.class)
public interface ProductClient {
    @GetMapping("/product/list")
    String productList(@RequestParam("msg") String msg);

    /**
     * 回滚事件,需要实现要回滚的对象接口,该回滚是被调用方要执行的业务逻辑.
     */
    @Slf4j
    @Component
    class ProductClientFallback implements ProductClient {

        @Override
        public String productList(String msg) {
            String info = "productList fallback()";
            log.info(info);
            return info;
        }
    }
}

 

在另外一个模块中引用该Client所在的模块.

然后直接注入即可使用.

   @Autowired
    private ProductClient productClient;
 /**
     * HystrixCommand(fallbackMethod = "fallback") 指定单FeignClient不可用或者执行时抛出异常,需要回滚的方法
     *
     * @return
     */
    @GetMapping("/feign/list")
    @HystrixCommand(fallbackMethod = "fallback")
    public String feignList() {
        return productClient.productList("Fetch feign msg...");
    }

  /**
  * 该回滚是当前调用方执行失败时的回滚.
  */
public String fallback() { return "invoke fallback()"; }

或者实现 FallbackProvider 接口,实习该接口后, fallbackMethod 就不会生效了.

package com.xmut.osm.zuul.filter;

import com.alibaba.fastjson.JSON;
import com.xmut.osm.common.bean.ResultVO;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.AbstractClientHttpResponse;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author 阮胜
 * @date 2018/7/22 20:01
 */
@Component
public class DefaultFallbackProviderImpl implements FallbackProvider {
    @Override
    public String getRoute() {
        return null;
    }

    @Override
    public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
        return new AbstractClientHttpResponse() {
            @Override
            public int getRawStatusCode() throws IOException {
                return HttpStatus.OK.value();
            }

            @Override
            public String getStatusText() throws IOException {
                return HttpStatus.OK.name();
            }

            @Override
            public void close() {

            }

            @Override
            public InputStream getBody() throws IOException {
                ResultVO<String> resultVO = new ResultVO<>();
                resultVO.setMessage("服务器正忙!");
                resultVO.setSuccess(false);
                return new ByteArrayInputStream(JSON.toJSONString(resultVO).getBytes());
            }

            @Override
            public HttpHeaders getHeaders() {
                HttpHeaders httpHeaders = new HttpHeaders();
                httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
                return httpHeaders;
            }
        };
    }
}

 

 最后,需要在调用FeignClient的那一方配置文件中添加如下配置:

feign:
hystrix:
enabled: true
posted @ 2018-07-20 15:12  cearnach  阅读(1090)  评论(0编辑  收藏  举报