一、直接通过配置文件配置路由
这是最简单的配置方式
zuul:
routes:
baidu:
url: http://www.baidu.com/**
这种方式将http://localhost:8080/baidu/**
转到http://www.baidu.com/**
。
二、修改ZuulProperties实现路由配置
如果要转发的路由太多,不可能全部写在配置文件中,可以在数据库中获取配置,然后封装ZuulProperties。
@Bean
public SimpleRouteLocator zuulRouteLocator(ZuulProperties zuulProperties, IZuulRouteDataRepository dataRepository) {
Map<String, ZuulProperties.ZuulRoute> routeMap = zuulProperties.getRoutes();
List<ZuulRouteData> data = dataRepository.findAll();
ZuulProperties.ZuulRoute zuulRoute;
for (ZuulRouteData routeData : data) {
zuulRoute = new ZuulProperties.ZuulRoute();
// 如path = "baidu"
String path = routeData.getPath();
zuulRoute.setId(path);
zuulRoute.setPath("/" + path + "/**");
zuulRoute.setUrl(routeData.getUrl());
zuulRoute.setRetryable(false);
zuulRoute.setStripPrefix(true);
zuulRoute.setSensitiveHeaders(new HashSet<>());
routeMap.put(path, zuulRoute);
}
zuulProperties.setRoutes(routeMap);
return new SimpleRouteLocator("", zuulProperties);
}
这种实现方式效果如方式一,相当于从数据库封装好ZuulProperties路由信息。
三、自定义RouteLocator实现动态路由配置
-
自定义RouteLocator。数据从redis中获取。实现RefreshableRouteLocator用于动态刷新路由配置。
@Slf4j public class ZuulRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator { private ZuulProperties properties; private StringRedisTemplate redisTemplate; public ZuulRouteLocator(String servletPath, ZuulProperties properties, StringRedisTemplate redisTemplate) { super(servletPath, properties); this.properties = properties; this.redisTemplate = redisTemplate; } @Override public void refresh() { doRefresh(); } @Override protected Map<String, ZuulProperties.ZuulRoute> locateRoutes() { LinkedHashMap<String, ZuulProperties.ZuulRoute> routesMap = new LinkedHashMap<>(); //从application.properties中加载路由信息 routesMap.putAll(super.locateRoutes()); //从db中加载路由信息 routesMap.putAll(locateRoutesFromRedis()); //优化一下配置 LinkedHashMap<String, ZuulProperties.ZuulRoute> values = new LinkedHashMap<>(); for (Map.Entry<String, ZuulProperties.ZuulRoute> entry : routesMap.entrySet()) { String path = entry.getKey(); // Prepend with slash if not already present. if (!path.startsWith(HsbConstants.PREFIX.value)) { path = HsbConstants.PREFIX.value + path; } if (StringUtils.hasText(this.properties.getPrefix())) { path = this.properties.getPrefix() + path; if (!path.startsWith(HsbConstants.PREFIX.value)) { path = HsbConstants.PREFIX.value + path; } } values.put(path, entry.getValue()); log.info("Created route configuration,path:{},route:{}", path, JSON.toJSONString(entry.getValue())); } log.info("Created all route configuration,the count is:{}", values.size()); return values; } private Map<String, ZuulProperties.ZuulRoute> locateRoutesFromRedis() { Map<String, ZuulProperties.ZuulRoute> routes = new LinkedHashMap<>(); //所有第三方系统 List<Object> thirdPartySystemList = redisTemplate.opsForHash().values("thirdPartySystem"); ZuulProperties.ZuulRoute zuulRoute; for (Object msg : thirdPartySystemList) { if (StringUtils.isEmpty(msg)) { continue; } ThirdPartySystem thirdPartySystem = JSONObject.parseObject(msg.toString(), ThirdPartySystem.class); if (thirdPartySystem == null) { continue; } //系统标识,作为转发到第三方系统的唯一标识 String identification = thirdPartySystem.getIdentification(); if (StringUtils.isEmpty(identification)) { continue; } String url = thirdPartySystem.getAddress(); if (StringUtils.isEmpty(url)) { continue; } zuulRoute = new ZuulProperties.ZuulRoute(); zuulRoute.setSensitiveHeaders(new HashSet<>()); zuulRoute.setRetryable(false); zuulRoute.setId(identification); zuulRoute.setPath(HsbConstants.PREFIX.value + identification + "/**"); zuulRoute.setUrl(url); zuulRoute.setStripPrefix(true); routes.put(zuulRoute.getPath(), zuulRoute); } return routes; } }
-
动态刷新路由配置。
@Service @Slf4j public class RefreshRouteService { private final ApplicationEventPublisher publisher; private final RouteLocator routeLocator; @Autowired public RefreshRouteService(ApplicationEventPublisher publisher, RouteLocator routeLocator) { this.publisher = publisher; this.routeLocator = routeLocator; } public void refreshRoute() { RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(routeLocator); publisher.publishEvent(routesRefreshedEvent); log.info("Updating route configuration"); } }
简单的路由配置。如果路由比较多,但是不复杂,可以直接使用
SimpleRouteLocator
来实现。如:
@Bean
public SimpleRouteLocator zuulRouteLocator(ZuulProperties zuulProperties, IZuulRouteDataRepository dataRepository) {
Map<String, ZuulProperties.ZuulRoute> routeMap = zuulProperties.getRoutes();
List<ZuulRouteData> data = dataRepository.findAll();
ZuulProperties.ZuulRoute zuulRoute;
for (ZuulRouteData routeData : data) {
zuulRoute = new ZuulProperties.ZuulRoute();
String path = routeData.getPath();
zuulRoute.setId(path);
zuulRoute.setPath("/" + path + "/**");
zuulRoute.setUrl(routeData.getUrl());
zuulRoute.setRetryable(false);
zuulRoute.setStripPrefix(true);
zuulRoute.setSensitiveHeaders(new HashSet<>());
routeMap.put(path, zuulRoute);
}
zuulProperties.setRoutes(routeMap);
return new SimpleRouteLocator("", zuulProperties);
}