在Zuul网关中,一个请求从进入zuul到转发到后端服务的完整过程
在Zuul网关中,一个请求从进入zuul到转发到后端服务的完整过程如下:
请求处理完整流程
1. 请求入口
- 请求首先到达Zuul Servlet(
ZuulServlet
) - 触发Zuul的过滤器链执行
2. 路由定位过程
// 通过 pre 路由阶段的过滤器(如 PreDecorationFilter)触发路由匹配
public Route getMatchingRoute(String path) {// 提取路径信息和服务版本String contextPath = getPathContext(path); String systemVersion = modulePathMap.get(contextPath);String version = getVersionFromPath(path);// 路径重写处理path = rewritePath(path, version);// 版本兼容性检查和转换if (!version.equals(systemVersion) && VersionUtils.isVersionCompatible(version, systemVersion)) {path = path.replace(version, systemVersion);}// 最终路由匹配return getSimpleMatchingRoute(path);
}
3. 负载均衡节点选择
// 在 getZuulRoute 中选择具体的服务实例
protected ZuulRoute getZuulRoute(String adjustedPath) {// 匹配路由规则for (Map.Entry<String, ZuulRoute> entry : super.getRoutesMap().entrySet()){String pattern = (String)entry.getKey();if (this.pathMatcher.match(pattern, adjustedPath)) {ZuulRoute zuulRoute = (ZuulRoute)entry.getValue();// 负载均衡选择具体节点return chooseZuulRouteForBalance(pattern, zuulRoute);}}
}// 随机负载均衡算法选择服务节点
private ZuulRoute chooseZuulRouteForBalance(String path, ZuulRoute defaultZuulRoute) {List<ZuulRoute> serviceZuulRoutes = currentZuulRoute.get(path);// 从多个服务实例中随机选择一个Random random = new Random();ZuulRoute zuulRoute = serviceZuulRoutes.get(random.nextInt(serviceZuulRoutes.size()));return zuulRoute;
}
4. 路由信息设置
- 通过
PreDecorationFilter
设置路由相关信息到请求上下文 [RequestContext](file://com\netflix\zuul\context\RequestContext.java#L13-L93) - 主要设置的属性包括:
serviceId
: 目标服务IDrouteHost
: 目标服务URLrequestURI
: 请求URI
5. 请求转发执行
- 在 route 阶段,
RibbonRoutingFilter
或SimpleHostRoutingFilter
执行实际的请求转发 - 如果是服务ID方式,使用
RibbonRoutingFilter
结合Ribbon进行负载均衡调用 - 如果是URL方式,使用
SimpleHostRoutingFilter
直接HTTP转发
6. 响应返回
- 后端服务处理完成后,响应通过Zuul的 post 过滤器链返回给客户端
关键代码流程
- 路由匹配:
getSimpleMatchingRoute()
- 节点选择:
getZuulRoute()
→chooseZuulRouteForBalance()
[CustomRouteLocator.java]
- 上下文设置:
PreDecorationFilter
过滤器 - 请求转发:
RibbonRoutingFilter
或SimpleHostRoutingFilter
- 响应处理: post 过滤器链
这个过程确保了请求能够根据路由规则正确地转发到后端服务,并支持负载均衡、路径重写、版本兼容等高级功能。