Spring Cloud Edgware对Hystrix回退的逻辑进行了一些改进。本文将信息探讨新旧版本的回退操作,并分析的原因及改进后的优势。
Dalston及更低版本
对于Dalston及更低版本,要想为Zuul提供回退,只需编写代码如下:
-
@Component
-
public class MyFallbackProvider implements ZuulFallbackProvider {
-
@Override
-
public String getRoute() {
-
// 表明是为哪个微服务提供回退,*表示为所有微服务提供回退
-
return "*";
-
}
-
-
@Override
-
public ClientHttpResponse fallbackResponse() {
-
return new ClientHttpResponse() {
-
@Override
-
public HttpStatus getStatusCode() throws IOException {
-
// fallback时的状态码
-
return HttpStatus.OK;
-
}
-
-
@Override
-
public int getRawStatusCode() throws IOException {
-
// 数字类型的状态码,本例返回的其实就是200,详见HttpStatus
-
return this.getStatusCode().value();
-
}
-
-
@Override
-
public String getStatusText() throws IOException {
-
// 状态文本,本例返回的其实就是OK,详见HttpStatus
-
return this.getStatusCode().getReasonPhrase();
-
}
-
-
@Override
-
public void close() {
-
}
-
-
@Override
-
public InputStream getBody() throws IOException {
-
// 响应体
-
return new ByteArrayInputStream("用户微服务不可用,请稍后再试。".getBytes());
-
}
-
-
@Override
-
public HttpHeaders getHeaders() {
-
// headers设定
-
HttpHeaders headers = new HttpHeaders();
-
MediaType mt = new MediaType("application", "json", Charset.forName("UTF-8"));
-
headers.setContentType(mt);
-
-
return headers;
-
}
-
};
-
}
-
}
Edgware及更高版本
-
@Component
-
public class MyFallbackProvider implements FallbackProvider {
-
@Override
-
public String getRoute() {
-
// 表明是为哪个微服务提供回退,*表示为所有微服务提供回退
-
return "*";
-
}
-
-
@Override
-
public ClientHttpResponse fallbackResponse(Throwable cause) {
-
if (cause instanceof HystrixTimeoutException) {
-
return response(HttpStatus.GATEWAY_TIMEOUT);
-
} else {
-
return this.fallbackResponse();
-
}
-
}
-
-
@Override
-
public ClientHttpResponse fallbackResponse() {
-
return this.response(HttpStatus.INTERNAL_SERVER_ERROR);
-
}
-
-
private ClientHttpResponse response(final HttpStatus status) {
-
return new ClientHttpResponse() {
-
@Override
-
public HttpStatus getStatusCode() throws IOException {
-
return status;
-
}
-
-
@Override
-
public int getRawStatusCode() throws IOException {
-
return status.value();
-
}
-
-
@Override
-
public String getStatusText() throws IOException {
-
return status.getReasonPhrase();
-
}
-
-
@Override
-
public void close() {
-
}
-
-
@Override
-
public InputStream getBody() throws IOException {
-
return new ByteArrayInputStream("服务不可用,请稍后再试。".getBytes());
-
}
-
-
@Override
-
public HttpHeaders getHeaders() {
-
// headers设定
-
HttpHeaders headers = new HttpHeaders();
-
MediaType mt = new MediaType("application", "json", Charset.forName("UTF-8"));
-
headers.setContentType(mt);
-
return headers;
-
}
-
};
-
}
-
}
分析
由代码可知:
-
Dalston及更低版本通过实现
ZuulFallbackProvider
接口,从而实现回退; -
Edgware及更高版本通过实现
FallbackProvider
接口,从而实现回退。 -
在Edgware中:
-
FallbackProvider是ZuulFallbackProvider的子接口。
-
ZuulFallbackProvider已经被标注
Deprecated
,很可能在未来的版本中被删除。 -
FallbackProvider接口比ZuulFallbackProvider多了一个
ClientHttpResponsefallbackResponse(Throwablecause);
方法,使用该方法,可获得造成回退的原因。 -
笔者将在下一篇文章详细总结在Spring Cloud中如何获得造成回退原因的各种姿势。