当我们的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() {

			}

		};
	}

}

  

12-22 03:18