zuul网关
- zuul自定义过滤器
- hystrix和ribbon时间
- RibbonAutoConfiguration自动配置
- FeignAutoConfiguration自动配置
- RibbonEurekaAutoConfiguration
- SendErrorFilter过滤器
- @EnableZuulServer
- HasFeatures
- @EnableZuulProxy
zuul自定义过滤器
- 继承ZuulFilter类,实现其方法filterType()、filterOrder()、shouldFilter()、run()
- filterType()表示过滤器的类型:pre-前置过滤器,用于请求处理前;route-路由过滤器,用于路由请求;post-后置过滤器,用于响应请求;error-错误过滤器,用于处理错误情况。
- filterOrder()表示过滤器的执行顺序,较小意味着先执行
- shouldFilter()表示是否执行过滤器的逻辑,可以编写逻辑确定是否执行过滤器
- run(),过滤器的实际执行逻辑
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;public class CustomFilter extends ZuulFilter {@Overridepublic String filterType() {return "pre"; // 前置过滤器}@Overridepublic int filterOrder() {return 1; // 执行顺序,数字越小越早执行}@Overridepublic boolean shouldFilter() {return true; // 在该方法中可以定义过滤器是否执行的逻辑}@Overridepublic 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自动配置
// 注入属性
@Autowired(required = false)
private List<RibbonClientSpecification> configurations = new ArrayList<>();
FeignAutoConfiguration自动配置
@Bean
public FeignContext feignContext() {FeignContext context = new FeignContext();context.setConfigurations(this.configurations);return context;
}
RibbonEurekaAutoConfiguration
SendErrorFilter过滤器
sendErrorFilter.ran请求上下为true则不执行这个默认过滤器
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;@Overridepublic String filterType() {return ERROR_TYPE;}@Overridepublic int filterOrder() {return SEND_ERROR_FILTER_ORDER;}@Overridepublic boolean shouldFilter() {RequestContext ctx = RequestContext.getCurrentContext();// only forward to errorPath if it hasn't been forwarded to alreadyreturn ctx.getThrowable() != null&& !ctx.getBoolean(SEND_ERROR_FILTER_RAN, false);}@Overridepublic 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 filtersif(throwable.getCause().getCause() instanceof ZuulException) {return new ZuulExceptionHolder((ZuulException) throwable.getCause().getCause());}}if (throwable.getCause() instanceof ZuulException) {// wrapped zuul exceptionreturn new ZuulExceptionHolder((ZuulException) throwable.getCause());}if (throwable instanceof ZuulException) {// exception thrown by zuul lifecyclereturn new ZuulExceptionHolder((ZuulException) throwable);}// fallbackreturn 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;}@Overridepublic Throwable getThrowable() {return this.throwable;}}protected static class ZuulExceptionHolder implements ExceptionHolder {private final ZuulException exception;public ZuulExceptionHolder(ZuulException exception) {this.exception = exception;}@Overridepublic Throwable getThrowable() {return this.exception;}@Overridepublic int getStatusCode() {return this.exception.nStatusCode;}@Overridepublic String getErrorCause() {return this.exception.errorCause;}}public void setErrorPath(String errorPath) {this.errorPath = errorPath;}}
@EnableZuulServer
ZuulServerAutoConfiguration自动注入的类
将应用程序设置为没有任何内置反向代理特性的通用Zuul服务器。到Zuul服务器的路由可以通过ZuulProperties配置(默认情况下没有)
HasFeatures
@EnableZuulProxy
设置一个Zuul服务器端点,并在其中安装一些反向代理过滤器,这样它就可以将请求转发到后端服务器。后端可以通过配置手工注册,也可以通过DiscoveryClient注册。
- ServiceRouteMapper
- DiscoveryClientRouteLocator
- HasFeatures
- HttpClientConfiguration(Import)
- ApacheHttpClientConnectionManagerFactory
- HttpClientBuilder
- ApacheHttpClientFactory
- RibbonCommandFactoryConfiguration.HttpClientRibbonConfiguration.class(Import)
- RibbonCommandFactory
- PreDecorationFilter
- RibbonRoutingFilter
- SimpleHostRoutingFilter