原创地址,jsbintask的博客(食用效果最佳),转载请注明出处!java
上一篇介绍了SpringCloud使用Zuul的调用流程
,明白了Zuul的工做原理关键在于ZuulServlet和它的内置Filter,因此在实际工做中,编写业务逻辑的关键就在于自定义filter。spring
实现一个自定义Filter很简单,继承自ZuulFilter
便可:api
@Component
public class Filter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext context = RequestContext.getCurrentContext().getRequest();
HttpServletRequest request = context.getRequest();
HttpServletResponse response = context.getResponse();
System.out.println("Filter.run");
return null;
}
}
复制代码
同类型filter执行顺序
RequestContext.getCurrentContext()
拿出。Zuul的Filter一共分为四个种类,Pre
,Route
,Post
,Error
,每种Filter的执行时机不一样,因此他们在业务逻辑功能上有所不一样,如图: app
限流
,权限控制
等。zuul内部已经定义了各类类型的filter,如预处理,路由转发,错误处理等。咱们能够经过源码来研究Zuul是如何帮咱们转发请求的: 负载均衡
RibbonRoutingFilter
SimpleHostRoutingFilter
SendForwardFilter
上面三个Filter只会执行一个,控制它们执行过程的为PreDecorationFilter
:
zuul:
prefix: /api
routes:
espay-auth:
path: /test/**
service-id: service-name
复制代码
这个时候将调用RibbonRoutingFilter做负载均衡转发请求:ide
protected ClientHttpResponse forward(RibbonCommandContext context) throws Exception {
Map<String, Object> info = this.helper.debug(context.getMethod(),
context.getUri(), context.getHeaders(), context.getParams(),
context.getRequestEntity());
RibbonCommand command = this.ribbonCommandFactory.create(context);
try {
ClientHttpResponse response = command.execute();
this.helper.appendDebug(info, response.getRawStatusCode(), response.getHeaders());
return response;
}
catch (HystrixRuntimeException ex) {
return handleException(info, ex);
}
}
复制代码
而当咱们配置的直接为某个地址:微服务
zuul:
routes:
espay-auth:
path: /auth/**
url: http://baidu.com
复制代码
则会调用SimpleHostRoutingFilter进行转发,它内部直接使用HttpClient进行转发: post
SendErrorFilter
处理,它会设置标志位
SEND_ERROR_FILTER_RAN
为true,而后从新发送请求到
PreDecorationFilter
。这个时候的流程为:
RibbonRoutingFilter
,普通http转发的SimpleHostRoutingFilter
.关注我,这里只有干货!
this
相关文章: SpringCloud-Zuul(一):技术选型及请求流程源码走读url