今天项目中用到动态路由机制,网上也找了一些相关的代码,最终实现动态路由,在这里记录一下,项目中将相关代码写在了zuulServer服务中。
第一步:重写路由定位器,
public class DynamicRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {
@Autowired
private RouterService routerService;
private ZuulProperties properties;
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<>();
// 加载application.yml中的路由表
routesMap.putAll(super.locateRoutes());
// System.out.println("zuul zuul from yml");
// System.out.println(super.locateRoutes());
// 加载db中的路由表
routesMap.putAll(locateRoutesFromDB());
// System.out.println("zuul zuul from DB");
// System.out.println(locateRoutesFromDB());
// 统一处理一下路由path的格式
LinkedHashMap<String, ZuulProperties.ZuulRoute> values = new LinkedHashMap<>();
for (Map.Entry<String, ZuulProperties.ZuulRoute> entry : routesMap.entrySet()) {
String path = entry.getKey();
if (!path.startsWith("/")) {
path = "/" + path;
}
if (StringUtils.hasText(this.properties.getPrefix())) {
path = this.properties.getPrefix() + path;
if (!path.startsWith("/")) {
path = "/" + path;
}
}
values.put(path, entry.getValue());
}
System.out.println("路由表:" + values);
return values;
}
private Map<String, ZuulProperties.ZuulRoute> locateRoutesFromDB() {
Map<String, ZuulProperties.ZuulRoute> routes = new LinkedHashMap<>();
List<GatewayApiRouteDO> results = (List<GatewayApiRouteDO>) routerService.findAllEnableRouter().getData();
for (GatewayApiRouteDO result : results) {
if (StringUtils.isEmpty(result.getPath()) ) {
continue;
}
if (StringUtils.isEmpty(result.getServiceId()) && StringUtils.isEmpty(result.getUrl())) {
continue;
}
ZuulProperties.ZuulRoute zuulRoute = new ZuulProperties.ZuulRoute();
try {
BeanUtils.copyProperties(result, zuulRoute);
} catch (Exception e) {
e.printStackTrace();
}
routes.put(zuulRoute.getPath(), zuulRoute);
}
return routes;
}
}
第二步:在DynamicRouteConfiguration 类中配置刚刚写好的路由定位器。
@Configuration
public class DynamicRouteConfiguration {
@Autowired
private ZuulProperties zuulProperties;
@Autowired
private ServerProperties server;
@Bean
public DynamicRouteLocator routeLocator() {
DynamicRouteLocator routeLocator = new DynamicRouteLocator(
this.server.getServletPrefix(), this.zuulProperties);
return routeLocator;
}
}
第三步:定时刷新路由表
@Component
@Configuration
@EnableScheduling
public class RefreshRouteTask {
private static final Logger log = LoggerFactory.getLogger(RefreshRouteTask.class);
@Autowired
private ApplicationEventPublisher publisher;
@Autowired
private RouteLocator routeLocator;
@Scheduled(fixedRate = 30000)
private void refreshRoute() {
log.info("刷新路由表");
RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(routeLocator);
publisher.publishEvent(routesRefreshedEvent);
}
}
以上就是实现动态路由的主要代码了,思路不难,欢迎留言探讨。
参考资料:https://www.jb51.net/article/150131.htm