Spring Cloud Zuul 获取当前请求的路由信息和路由后端的服务节点信息
基本思路
参考spring-cloud-zuul-ratelimit开源项目,在过滤器中根据当前的请求路径,判断当前的路由信息,当取得路由信息后,可以对服务的调用次数做统计等操作。
具体实现
创建一个AbstractRouteFilter
public abstract class AbstractRouteFilter extends ZuulFilter {
private final RouteLocator routeLocator;
private final UrlPathHelper urlPathHelper;
AbstractRouteFilter(RouteLocator routeLocator,UrlPathHelper urlPathHelper){
this.routeLocator = routeLocator;
this.urlPathHelper = urlPathHelper;
}
//核心逻辑,获取请求路径,利用RouteLocator返回路由信息
protected Route route(HttpServletRequest request){
String requestURI = urlPathHelper.getPathWithinApplication(request);
return routeLocator.getMatchingRoute(requestURI);
}
}
使用时,继承AbstractRouteFilter即可,下面演示一个服务调用次数的过滤器示例
示例
public class RouteTimesFilter extends AbstractRouteFilter {
public RouteTimesFilter(RouteLocator routeLocator, UrlPathHelper urlPathHelper) {
super(routeLocator,urlPathHelper);
}
@Override
public String filterType() {
//可以根据业务要求,修改过滤器类型
return "post";
}
@Override
public int filterOrder() {
//过滤器顺序
return 0;
}
@Override
public boolean shouldFilter() {
//可以根据业务要求,过滤相关路由
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
Route route = route(ctx.getRequest());
//获取到路由信息,就可以做想要做的事了
System.out.println(route);
return null;
}
}
配置过滤器
@Component
public class ZuulFilterConfig {
@Bean
public ZuulFilter routeTimesFilter(RouteLocator routeLocator){
return new RouteTimesFilter(routeLocator,new UrlPathHelper());
}
}
路由到后端的服务节点信息
/**
* 打印目标节点地址
* @param logMap
* @param ctx
*/
private void printTargetUri(Map<String, Object> logMap,RequestContext ctx) {
//打印targetUri
if((Boolean) ctx.get("isSuccess")){
RibbonHttpResponse ribbonHttpResponse = (RibbonHttpResponse)ctx.get("zuulResponse");
URI uri=null;
try {
//反射获取私有成员变量
RibbonApacheHttpResponse ribbonApacheHttpResponse = (RibbonApacheHttpResponse)ReflectionUtils.
getPrivateField(ribbonHttpResponse,"response");
uri = ribbonApacheHttpResponse.getRequestedURI();
logger.info("targetUri:"+uri);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}catch (IllegalAccessException ie){
ie.printStackTrace();
}
}
}
定位问题原因*
根据原因思考问题解决方案*
实践验证方案有效性*
提交验证结果