A, description,
The core concept of gateway is routing configuration and routing rules. As the entrance of all request traffic, it is necessary to avoid restarts in the actual production environment to ensure high reliability and availability. Therefore, dynamic routing is very necessary. This article mainly introduces the implementation ideas, and Nacos as the data source to explain
2. Key points of implementation
To implement dynamic routing, focus on the following four points
- When the gateway is started,
Dynamic routing
How is the data loaded in Static routing
withDynamic routing
Ps:Static routing
This refers to the route configuration that is written to death in the configuration file- Listening to the
Dynamic routing
Data source changes of - What happens when the data changes
Inform zuul
The refresh routing
Third, concrete implementation
3.1. Realize data loading of dynamic routing
- rewrite
SimpleRouteLocator
Of the classlocateRoutes
Method, this method is to load the route configuration, the parent class is to obtain the route configuration in the properties, you can extend this method, to achieve the purpose of dynamic obtain configuration - Here the
Static routing
withDynamic routing
Coexist with the same route IDDynamic routing
Implementation of priority coverage
AbstractDynRouteLocator class to view: AbstractDynRouteLocator. Java
public abstract class AbstractDynRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {
private ZuulProperties properties;
public AbstractDynRouteLocator(String servletPath, ZuulProperties properties) {
super(servletPath, properties);
this.properties = properties;
}
/**
* 刷新路由
*/
@Override
public void refresh(a) {
doRefresh();
}
@Override
protected Map<String, ZuulRoute> locateRoutes(a) {
LinkedHashMap<String, ZuulRoute> routesMap = new LinkedHashMap<>();
// Load static routing information from application.properties
routesMap.putAll(super.locateRoutes());
// Load dynamic routing information from the data source
routesMap.putAll(loadDynamicRoute());
// Optimize the configuration
LinkedHashMap<String, ZuulRoute> values = new LinkedHashMap<>();
for (Map.Entry<String, ZuulRoute> entry : routesMap.entrySet()) {
String path = entry.getKey();
// Prepend with slash if not already present.
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());
}
return values;
}
/** * loads the route configuration, which is implemented by subclasses */
public abstract Map<String, ZuulRoute> loadDynamicRoute(a);
}
Copy the code
Because dynamic routing data can be in many ways, such as: Nacos, Redis, Zookeeper, DB, etc., so here defines an abstract class, by the concrete implementation class to define loadDynamicRoute method
3.2. Nacos Routing implementation class
NacosDynRouteLocator class complete code can be viewed: NacosDynRouteLocator. Java
3.2.1. AchieveloadDynamicRoute
Method to obtain dynamic data
@Override
public Map<String, ZuulProperties.ZuulRoute> loadDynamicRoute() {
Map<String, ZuulRoute> routes = new LinkedHashMap<>();
if (zuulRouteEntities == null) {
zuulRouteEntities = getNacosConfig();
}
for (ZuulRouteEntity result : zuulRouteEntities) {
if(StrUtil.isBlank(result.getPath()) || ! result.isEnabled()) {continue;
}
ZuulRoute zuulRoute = new ZuulRoute();
BeanUtil.copyProperties(result, zuulRoute);
routes.put(zuulRoute.getPath(), zuulRoute);
}
return routes;
}
private List<ZuulRouteEntity> getNacosConfig(a) {
try {
String content = nacosConfigProperties.configServiceInstance().getConfig(ZUUL_DATA_ID, ZUUL_GROUP_ID,5000);
return getListByStr(content);
} catch (NacosException e) {
log.error("listenerNacos-error", e);
}
return new ArrayList<>(0);
}
Copy the code
Increased 3.2.2.NacosListener
Monitor routing data changes
private void addListener(a) {
try {
nacosConfigProperties.configServiceInstance().addListener(ZUUL_DATA_ID, ZUUL_GROUP_ID, new Listener() {
@Override
public Executor getExecutor(a) {
return null;
}
@Override
public void receiveConfigInfo(String configInfo) {
// Assign routing information
locator.setZuulRouteEntities(getListByStr(configInfo));
RoutesRefreshedEvent routesRefreshedEvent = newRoutesRefreshedEvent(locator); publisher.publishEvent(routesRefreshedEvent); }}); }catch (NacosException e) {
log.error("nacos-addListener-error", e); }}Copy the code
Zuul has a ZuulRefreshListener class that listens for the event to refresh the route for us
3.3. Configuration class creationNacosDynRouteLocator
The Bean
DynamicZuulRouteConfig to view: NacosDynRouteLocator. Java
@Configuration
@ConditionalOnProperty(prefix = "zlt.gateway.dynamicRoute", name = "enabled", havingValue = "true")
public class DynamicZuulRouteConfig {
@Autowired
private ZuulProperties zuulProperties;
@Autowired
private DispatcherServletPath dispatcherServletPath;
/** * Nacos implementation */
@Configuration
@ConditionalOnProperty(prefix = "zlt.gateway.dynamicRoute", name = "dataType", havingValue = "nacos", matchIfMissing = true)
public class NacosZuulRoute {
@Autowired
private NacosConfigProperties nacosConfigProperties;
@Autowired
private ApplicationEventPublisher publisher;
@Bean
public NacosDynRouteLocator nacosDynRouteLocator(a) {
return newNacosDynRouteLocator(nacosConfigProperties, publisher, dispatcherServletPath.getPrefix(), zuulProperties); }}}Copy the code
You can customize the configuration to control whether to enable dynamic routing
Add 3.4.Nacos
The routing configuration
- Data Id: zuul – routes
- Group: ZUUL_GATEWAY
- Configuration contents:
[{"enabled":true."id":"csdn"."path":"/csdn/**"."retryable":false."stripPrefix":true."url":"https://www.csdn.net/"
}, {
"enabled":true."id":"github"."path":"/github/**"."retryable":false."stripPrefix":true."url":"http://github.com/"}]Copy the code
Add two routes
Four, test,
- Enabling the Gateway
/actuator/routes
The endpoint displays the current routing information
You can see that static routes and the two routes configured in Nacos are displayed together
- Modify the
Nacos
Configure, closecsdn
routing
- Refresh View gateway routing information
CSDN routes are no longer visible, and dynamic route configuration is changed
Recommended reading
- Log troubleshooting difficulty? Distributed log link tracing to help you
- Zuul integrates Sentinel’s latest gateway flow control components
- Ali Registry Nacos production deployment solution
- Spring Boot custom configuration items implement automatic prompts in the IDE
Please scan the code to follow my official account