标签:ica object 参数 顺序 tac inter tco pre 范围
Zuul包括两部分内容:请求的路由和过滤。而实际上请求的路由也是通过过滤器实现的,例如理由映射主要通过pre类型的过滤器完成,它将请求路径与配置的路由规则进行匹配,找到需要转发的目标地址;请求转发的部分则是由route类型的过滤器来完成的,对pre类型过滤器获得的路由地址进行转发。所以过滤器时Zuul实现API网关功能最为核心的部件,每一个进入Zuul的Http请求都会经过一系列的过滤器处理链得到请求响应并返回给客户端。
过滤类型、执行顺序、执行条件、具体操作
过滤器类型 | 顺序 | 过滤器 | 功能 |
---|---|---|---|
pre | -3 | ServletDetectionFilter | 标记处理Servlet的类型 |
pre | -2 | Servlet30WrapperFilter | 包装HttpServletRequest请求 |
pre | -1 | FormBodyWrapperFilter | 包装请求体 |
pre | 1 | DebugFilter | 标记调试标志 |
pre | 5 | PreDecorationFilter | 处理请求上下文供后续使用 |
route | 10 | RibbonRoutingFilter | serviceId请求转发 |
route | 100 | SimpleHostRoutingFilter | url请求转发 |
route | 500 | SendForwordFilter | forward请求转发 |
post | 0 | SendErrorFilter | 处理有错误的请求响应 |
post | 1000 | SendResponseFilter | 处理正常处理的请求响应 |
对于可预知异常处理,可以使用SendErrorFilter处理
SendErrorFilter过滤器对异常处理的触发条件是,异常信息必须包含error.status_code错误信息,所以在进行异常处理的时候需要在异常信息中添加error.status_code信息用来出发SendErrorFilter。
对于不可预知的异常需要使用全局异常处理,即使用ErrorFilter处理
在请求生命周期的pre、route、post三个阶段中有异常抛出的时候都会进入error阶段的处理,所以可以创建一个error类型的过滤器来捕获这些异常信息,并根据这些异常信息在请求上下文中注入需要返回给客户端的错误描述。常见用法是,在try-catch中注入error信息,让SendErrorFilter捕获处理返回给客户端,eg:
public class ErrorFilter extends ZuulFilter
{
private static final Logger log = LoggerFactory.getLogger(ErrorFilter.class);
@Override
public String filterType()
{
return "error";
}
@Override
public int filterOrder()
{
return 10;
}
@Override
public boolean shouldFilter()
{
return true;
}
@Override
public Object run()
{
RequestContext ctx = RequestContext.getCurrentContext();
Throwable throwable = ctx.getThrowable();
log.error("this is a ErrorFilter:{}.", throwable.getCause().getMessage());
ctx.set("error.status_code", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
ctx.set("error.exception", throwable.getCause());
return null;
}
}
第一种是在开发过程中对异常的处理,第二种是对第一种的补充,防止意外异常发生
try{
preRoute();
}catch(ZuulException e){
error(e);
postRoute();
return;
}
try{
route();
}catch(ZuulException e){
error(e);
postRoute();
return;
}
try{
postRoute();
}catch(ZuulException){
error(e);
return;
}
在pre、route过滤器调用过程中,抛出异常都要经过error过滤器处理,然后再通过post返回客户端。但是,**如果在post中出现了异常,由error过滤器处理后并不会再调用post阶段的请求,这些error.*参数就不会被SendErrorFilter消费输出,会造成异常泄露**。
在error过滤器之后在加一层SendErrorFilter,用来执行post过滤器中抛出的异常
public class ErrorExtFilter extends SendErrorFilter
{
@Override
public String filterType()
{
return "error";
}
@Override
public int filterOrder()
{
return 30;
}
@Override
public boolean shouldFilter()
{
//TODO
return true;
}
}
那么怎样判断过滤器来自于哪个阶段呢,需要重写FilterProcessor核心过滤器类,在执行filter具体逻辑的方法processZuulFilter方法中对处理的filter进行标记
public class MarkFilterProcessor extends FilterProcessor
{
@Override
public Object processZuulFilter(ZuulFilter filter) throws ZuulException
{
try
{
return super.processZuulFilter(filter);
}
catch (ZuulException e)
{
RequestContext ctx = RequestContext.getCurrentContext();
ctx.set("failed.filter", filter);
throw e;
}
}
}
在shouldFilter方法中进行判断是不是post阶段抛出的异常
@Override
public boolean shouldFilter()
{
RequestContext ctx = RequestContext.getCurrentContext();
ZuulFilter failedFilter = (ZuulFilter) ctx.get("failed.filter");
if(failedFilter != null && failedFilter.filterType().equals("post"))
{
return true;
}
return false;
}
最后在主类中调用FilterProcessor.setProcessor(new MarkFilterProcessor());启动自定义的核心处理器
默认使用DefaultErrorAttributes作为默认异常信息接口,如果有ErrorAttributes接口的实现类,则不适用默认的,而使用实现类
public class MessageErrorAttributes extends DefaultErrorAttributes
{
@Override
public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace)
{
Map<String, Object> result = super.getErrorAttributes(requestAttributes, includeStackTrace);
result.remove("exception");
return result;
}
}
public DefaultErrorAttributes errorAttributes()
{
return new MessageErrorAttributes();
}
zuul.<filtername>.<filtertype>.disable=true
使用spring cloud config分布式配置中心实现application.properties/application.yarm动态加载
标签:ica object 参数 顺序 tac inter tco pre 范围
原文地址:https://www.cnblogs.com/nwu-edu/p/9629193.html