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