动态路由
- 自定义DynamicRouteLocator类继承SimpleRouteLocator,实现RefreshableRouteLocator接口
- RefreshRouteService.refreshRoute()刷新路由
URI匹配
重写getMatchingRoute()或者重写核心getZuulRoute()
核心类图zuul的路由规则处理核心类SimpleRouteLocator
getMatchingRoute()
核心代码 ZuulRoute route = getZuulRoute(adjustedPath);
- DynamicRouteLocator 代码
@Slf4j
public class DynamicRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {
public static final String PREFIX = "/";
private ZuulProperties properties;
private PathMatcher pathMatcher = new AntPathMatcher();
public DynamicRouteLocator(String servletPath, ZuulProperties properties) {
super(servletPath, properties);
this.properties = properties;
}
@Override
public void refresh() {
doRefresh();
}
@Override
protected Map<String, ZuulProperties.ZuulRoute> locateRoutes() {
LinkedHashMap<String, ZuulProperties.ZuulRoute> routesMap = new LinkedHashMap<>();
//自定义加载路由信息
routesMap.putAll(getRouteList());
//从配置文件中加载路由信息
routesMap.putAll(super.locateRoutes());
//优化一下配置
LinkedHashMap<String, ZuulProperties.ZuulRoute> values = new LinkedHashMap<>();
for (Map.Entry<String, ZuulProperties.ZuulRoute> entry : routesMap.entrySet()) {
String path = entry.getKey();
if (!path.startsWith(PREFIX)) {
path = PREFIX + path;
}
if (StringUtils.hasText(this.properties.getPrefix())) {
path = this.properties.getPrefix() + path;
if (!path.startsWith(PREFIX)) {
path = PREFIX + path;
}
}
values.put(path, entry.getValue());
}
return values;
}
/**
* 路由匹配规则重写
*/
@Override
protected ZuulProperties.ZuulRoute getZuulRoute(String adjustedPath) {
String tenant = TenantContext.getCurrentTenantContext();
if (!matchesIgnoredPatterns(adjustedPath)) {
for (Map.Entry<String, ZuulProperties.ZuulRoute> entry : getRoutesMap().entrySet()) {
String pattern = entry.getKey();
if (this.pathMatcher.match(pattern, adjustedPath)) {
return entry.getValue();
}
}
}
return null;
}
/**
* 获取zuul路由规则
*/
private LinkedHashMap<String, ZuulProperties.ZuulRoute> getRouteList() {
LinkedHashMap<String, ZuulProperties.ZuulRoute> result = new LinkedHashMap<>();
EtcdCacheInitializer.getServiceRouterMap().forEach((k, v) -> {
ZuulProperties.ZuulRoute zr = new ZuulProperties.ZuulRoute();
zr.setCustomSensitiveHeaders(v.getCustomSensitiveHeaders());
zr.setId(v.getId());
zr.setPath(v.getPath());
zr.setServiceId(v.getServiceId());
zr.setUrl(v.getUrl());
zr.setStripPrefix(v.getStripPrefix());
zr.setRetryable(v.getRetryable());
zr.setSensitiveHeaders(Sets.newHashSet());
result.put(v.getPath(), zr);
});
if (log.isDebugEnabled()) {
log.debug("router rules=[{}]", JSONUtil.toJsonStr(result));
}
return result;
}
}
- service调用
@Service
public class RefreshRouteService {
@Resource
private ApplicationEventPublisher publisher;
@Resource
private DynamicRouteLocator dynamicRouteLocator;
/**
* 动态路由实现,调用refreshRoute发布刷新路由事件
*/
public void refreshRoute() {
RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(dynamicRouteLocator);
publisher.publishEvent(routesRefreshedEvent);
}
}