当我们的zuul进行路由分发时,如果后端服务没有启动,或者调用超时,这时候我们希望Zuul提供一种降级功能,而不是将异常暴露出来。
Spring cloud zuul提供这种降级功能,操作步骤如下:
package microService.app.filter; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import javax.servlet.http.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpResponse; import org.springframework.stereotype.Component; import com.netflix.zuul.context.RequestContext; import net.sf.json.JSONObject; /** * 向用户管理路由发起请求失败时的回滚处理 hystrix的回滚能力 * */ @Component public class MsgCollectionFilter implements ZuulFallbackProvider { private final Logger logger = LoggerFactory.getLogger(MsgCollectionFilter.class); @Override public String getRoute() { return "*";// api服务id,如果需要所有调用都支持回退,则return "*"或return null } /** * 如果请求用户服务失败,返回什么信息给消费者客户端 */ @Override public ClientHttpResponse fallbackResponse() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); return new ClientHttpResponse() { @Override public InputStream getBody() throws IOException { JSONObject r = new JSONObject(); r.put("state", "8888"); r.put("msg", "系统错误,请求失败"); logger.error("降级"+r.toString()); return new ByteArrayInputStream(r.toString().getBytes("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() throws IOException { return HttpStatus.OK; } @Override public int getRawStatusCode() throws IOException { return HttpStatus.OK.value(); } @Override public String getStatusText() throws IOException { return HttpStatus.OK.getReasonPhrase(); } @Override public void close() { } }; } }