zuul网关

zuul网关

zuul自定义过滤器

  1. 继承ZuulFilter类,实现其方法filterType()、filterOrder()、shouldFilter()、run()
    1. filterType()表示过滤器的类型:pre-前置过滤器,用于请求处理前;route-路由过滤器,用于路由请求;post-后置过滤器,用于响应请求;error-错误过滤器,用于处理错误情况。
    2. filterOrder()表示过滤器的执行顺序,较小意味着先执行
    3. shouldFilter()表示是否执行过滤器的逻辑,可以编写逻辑确定是否执行过滤器
    4. run(),过滤器的实际执行逻辑
java 复制代码
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

public class CustomFilter extends ZuulFilter {

    @Override
    public String filterType() {
        return "pre"; // 前置过滤器
    }

    @Override
    public int filterOrder() {
        return 1; // 执行顺序,数字越小越早执行
    }

    @Override
    public boolean shouldFilter() {
        return true; // 在该方法中可以定义过滤器是否执行的逻辑
    }

    @Override
    public Object run() {
        // 获取请求的信息
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String uri = request.getRequestURI();
        // 获取请求信息、响应信息等
        // 对请求或响应进行处理
        if(auth(ctd)){
			ctx.setSendZuulResponse(false); // 不将请求路由到后端服务
            ctx.setResponseStatusCode("401"); 
            ctx.setResponseBody("Access Denied"); // 设置响应内容
            ctx.set("responseFiltered", true); // 标记该请求已被过滤
        }
        return null;
    }
}

hystrix和ribbon时间

Ribbon超时时间

Hystrix超时时间

配置文件

调用过程

RibbonAutoConfiguration自动配置

java 复制代码
// 注入属性
@Autowired(required = false)
private List<RibbonClientSpecification> configurations = new ArrayList<>();

FeignAutoConfiguration自动配置

java 复制代码
@Bean
public FeignContext feignContext() {
	FeignContext context = new FeignContext();
	context.setConfigurations(this.configurations);
	return context;
}

RibbonEurekaAutoConfiguration

SendErrorFilter过滤器

sendErrorFilter.ran请求上下为true则不执行这个默认过滤器

java 复制代码
public class SendErrorFilter extends ZuulFilter {

	private static final Log log = LogFactory.getLog(SendErrorFilter.class);
	protected static final String SEND_ERROR_FILTER_RAN = "sendErrorFilter.ran";

	@Value("${error.path:/error}")
	private String errorPath;

	@Override
	public String filterType() {
		return ERROR_TYPE;
	}

	@Override
	public int filterOrder() {
		return SEND_ERROR_FILTER_ORDER;
	}

	@Override
	public boolean shouldFilter() {
		RequestContext ctx = RequestContext.getCurrentContext();
		// only forward to errorPath if it hasn't been forwarded to already
		return ctx.getThrowable() != null
				&& !ctx.getBoolean(SEND_ERROR_FILTER_RAN, false);
	}

	@Override
	public Object run() {
		try {
			RequestContext ctx = RequestContext.getCurrentContext();
            // 获取异常信息
			ExceptionHolder exception = findZuulException(ctx.getThrowable());
			HttpServletRequest request = ctx.getRequest();
			
			request.setAttribute("javax.servlet.error.status_code", exception.getStatusCode());
			// 打印什么原因导致的异常异常的信息
			log.warn("Error during filtering", exception.getThrowable());
			request.setAttribute("javax.servlet.error.exception", exception.getThrowable());

			if (StringUtils.hasText(exception.getErrorCause())) {
				request.setAttribute("javax.servlet.error.message", exception.getErrorCause());
			}

			RequestDispatcher dispatcher = request.getRequestDispatcher(
					this.errorPath);
			if (dispatcher != null) {
				ctx.set(SEND_ERROR_FILTER_RAN, true);
				if (!ctx.getResponse().isCommitted()) {
					ctx.setResponseStatusCode(exception.getStatusCode());
					dispatcher.forward(request, ctx.getResponse());
				}
			}
		}
		catch (Exception ex) {
			ReflectionUtils.rethrowRuntimeException(ex);
		}
		return null;
	}

	protected ExceptionHolder findZuulException(Throwable throwable) {
		if (throwable.getCause() instanceof ZuulRuntimeException) {
			Throwable cause = null;
			if (throwable.getCause().getCause() != null) {
				cause = throwable.getCause().getCause().getCause();
			}
			if (cause instanceof ClientException && cause.getCause() != null
					&& cause.getCause().getCause() instanceof SocketTimeoutException) {

				ZuulException zuulException = new ZuulException("", 504,
						ZuulException.class.getName() + ": Hystrix Readed time out");
				return new ZuulExceptionHolder(zuulException);
			}
			// this was a failure initiated by one of the local filters
			if(throwable.getCause().getCause() instanceof ZuulException) {
				return new ZuulExceptionHolder((ZuulException) throwable.getCause().getCause());
			}
		}
		
		if (throwable.getCause() instanceof ZuulException) {
			// wrapped zuul exception
			return  new ZuulExceptionHolder((ZuulException) throwable.getCause());
		}

		if (throwable instanceof ZuulException) {
			// exception thrown by zuul lifecycle
			return new ZuulExceptionHolder((ZuulException) throwable);
		}

		// fallback
		return new DefaultExceptionHolder(throwable);
	}

	protected interface ExceptionHolder {
		Throwable getThrowable();

	    default int getStatusCode() {
	    	return HttpStatus.INTERNAL_SERVER_ERROR.value();
		}

	    default String getErrorCause() {
	    	return null;
		}
	}

	protected static class DefaultExceptionHolder implements ExceptionHolder {
		private final Throwable throwable;

		public DefaultExceptionHolder(Throwable throwable) {
			this.throwable = throwable;
		}

		@Override
		public Throwable getThrowable() {
			return this.throwable;
		}
	}

	protected static class ZuulExceptionHolder implements ExceptionHolder {
		private final ZuulException exception;

		public ZuulExceptionHolder(ZuulException exception) {
			this.exception = exception;
		}

		@Override
		public Throwable getThrowable() {
			return this.exception;
		}

		@Override
		public int getStatusCode() {
			return this.exception.nStatusCode;
		}

		@Override
		public String getErrorCause() {
			return this.exception.errorCause;
		}
	}

	public void setErrorPath(String errorPath) {
		this.errorPath = errorPath;
	}

}

@EnableZuulServer

ZuulServerAutoConfiguration自动注入的类

将应用程序设置为没有任何内置反向代理特性的通用Zuul服务器。到Zuul服务器的路由可以通过ZuulProperties配置(默认情况下没有)

HasFeatures

@EnableZuulProxy

设置一个Zuul服务器端点,并在其中安装一些反向代理过滤器,这样它就可以将请求转发到后端服务器。后端可以通过配置手工注册,也可以通过DiscoveryClient注册。

  1. ServiceRouteMapper
  2. DiscoveryClientRouteLocator
  3. HasFeatures
  4. HttpClientConfiguration(Import)
    1. ApacheHttpClientConnectionManagerFactory
    2. HttpClientBuilder
    3. ApacheHttpClientFactory
  5. RibbonCommandFactoryConfiguration.HttpClientRibbonConfiguration.class(Import)
    1. RibbonCommandFactory
  6. PreDecorationFilter
  7. RibbonRoutingFilter
  8. SimpleHostRoutingFilter
相关推荐
LiuYaoheng10 分钟前
【Android】View 的基础知识
android·java·笔记·学习
勇往直前plus18 分钟前
Sentinel微服务保护
java·spring boot·微服务·sentinel
星辰大海的精灵18 分钟前
SpringBoot与Quartz整合,实现订单自动取消功能
java·后端·算法
名誉寒冰19 分钟前
TCP, 三次握手, 四次挥手, 滑动窗口, 快速重传, 拥塞控制, 半连接队列, RST, SYN, ACK
网络·tcp/ip·php
塵觴葉19 分钟前
Linux内核网络的连接跟踪conntrack简单分析
linux·网络·conntrack
小鸡脚来咯21 分钟前
一个Java的main方法在JVM中的执行流程
java·开发语言·jvm
江团1io022 分钟前
深入解析三色标记算法
java·开发语言·jvm
天天摸鱼的java工程师30 分钟前
RestTemplate 如何优化连接池?—— 八年 Java 开发的踩坑与优化指南
java·后端
你我约定有三34 分钟前
java--泛型
java·开发语言·windows
☆璇38 分钟前
【Linux】Linux环境基础开发工具使用
linux·运维·服务器