结合DispatchServlet分析Zuul网关请求过程

基于Zuul1.3.1RELEASE进行分析,代码:https://github.com/tryandcatch/zuul

当一个请求到达Zuul的时候首先会经过一系列的 Filter(这里的FilterServlet下的)然后进入到DispatchServletdoDispatch方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
//...
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);
//...
}
//....
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
for (HandlerMapping hm : this.handlerMappings) {
if (logger.isTraceEnabled()) {
logger.trace(
"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
}
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
return null;
}
//....

getHandler()方法主要是根据请求遍历handlerMappings,调用HandlerMappinggetHandler()方法(HandlerMapping是个接口,在这里实际是调用的AbstractHandlerMappinggetHandler()方法),找出能够处理该请求的handler(HandlerExecutionChain)。

AbstractHandlerMappinggetHandler()方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//getHandlerInternal 是个抽象的方法,该处会调用其子类AbstractUrlHandlerMapping、AbstractHandlerMethodMapping中的方法
Object handler = getHandlerInternal(request);
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = getApplicationContext().getBean(handlerName);
}

HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
if (CorsUtils.isCorsRequest(request)) {
CorsConfiguration globalConfig = this.globalCorsConfigSource.getCorsConfiguration(request);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}

HandlerMappingAbstractHandlerMappingSimpleUrlHandlerMappingZuulHandlerMapping之间的关系:
ZuulHandlerMapping.png
SimpleUrlHandlerMapping.png

AbstractUrlHandlerMappinggetHandlerInternal方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
Object handler = lookupHandler(lookupPath, request);
if (handler == null) {
// We need to care for the default handler directly, since we need to
// expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.
Object rawHandler = null;
if ("/".equals(lookupPath)) {
rawHandler = getRootHandler();
}
if (rawHandler == null) {
rawHandler = getDefaultHandler();
}
if (rawHandler != null) {
// Bean name or resolved handler?
if (rawHandler instanceof String) {
String handlerName = (String) rawHandler;
rawHandler = getApplicationContext().getBean(handlerName);
}
validateHandler(rawHandler, request);
handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);
}
}
if (handler != null && logger.isDebugEnabled()) {
logger.debug("Mapping [" + lookupPath + "] to " + handler);
}
else if (handler == null && logger.isTraceEnabled()) {
logger.trace("No handler mapping found for [" + lookupPath + "]");
}
return handler;
}

Zuul中请求流程大致如下图:

ZuulRequestFlow.png