当我们的zuul进行路由分发时,如果后端服务没有启动,或者调用超时,这时候我们希望Zuul提供一种降级功能,而不是将异常暴露出来。
Spring cloud zuul提供这种降级功能,操作步骤如下:
1.在主函数上添加@EnbaleZuulProxy
注解。
2.定义将降级类,并实现FallbackProvider接口。(在Dalston版本需实现ZuulFallbackProvider,在Edgware.RC1之后版本实现FallbackProvider接口)。
@Component
public class FallBackHandler implements FallbackProvider {
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
if (cause != null && cause.getCause() != null) {
String reason = cause.getCause().getMessage();
//输出详细的回退原因
log.info("接口:" + route + ",fallback reason: {}", reason);
}
return new ClientHttpResponse() {
@Override
public InputStream getBody() {
// 当出现服务调用错误之后返回的数据内容
return new ByteArrayInputStream("{\"code\":-1,\"msg\":\"服务暂不可用\"}".getBytes(StandardCharsets.UTF_8));
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
//和body中的内容编码一致,否则容易乱码
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
return headers;
}
/**
* 网关向api服务请求是失败了,但是消费者客户端向网关发起的请求是OK的,
* 不应该把api的404,500等问题抛给客户端
* 网关和api服务集群对于客户端来说是黑盒子
*/
@Override
public HttpStatus getStatusCode() {
return HttpStatus.BAD_REQUEST;
}
@Override
public int getRawStatusCode() {
return HttpStatus.BAD_REQUEST.value();
}
@Override
public String getStatusText() {
return HttpStatus.BAD_REQUEST.getReasonPhrase();
}
@Override
public void close() {
}
};
}
@Override
public String getRoute() {
return "*";
}
}