1. Описание
Основной концепцией шлюза является конфигурация маршрутизации и правила маршрутизации.В качестве точки входа для всего трафика запросов, чтобы обеспечить высокую надежность и высокую доступность в реальной производственной среде, необходимо максимально избегать перезапуска, поэтому очень необходимо для реализации динамической маршрутизации; эта статья в основном знакомит с идеей реализации и использованияNacosОбъясните источник данных
2. Основные моменты реализации
Для реализации динамической маршрутизации нужно лишь обратить внимание на следующие 4 пункта
- Когда шлюз запустится,
动态路由как загрузить данные -
静态路由а также动态路由Что бы ни превалировало, ps:静态路由Относится к жестко запрограммированной конфигурации маршрутизации в файле конфигурации. - монитор
动态路由изменения источника данных - Что происходит при изменении данных
通知zuulобновить маршрут
В-третьих, конкретная реализация
3.1 Реализация загрузки данных для динамической маршрутизации
- переписать
SimpleRouteLocatorКатегорияlocateRoutesМетод, этот метод предназначен для загрузки конфигурации маршрутизации, родительский класс должен получить конфигурацию маршрутизации в свойствах, вы можете расширить этот метод для достижения цели динамического получения конфигурации - используется здесь
静态路由а также动态路由сосуществование, один и тот же идентификатор маршрута начинается с动态路由Реализация приоритетного покрытия
Класс AbstractDynRouteLocatorМожет просматривать: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() {
doRefresh();
}
@Override
protected Map<String, ZuulRoute> locateRoutes() {
LinkedHashMap<String, ZuulRoute> routesMap = new LinkedHashMap<>();
// 从application.properties中加载静态路由信息
routesMap.putAll(super.locateRoutes());
// 从数据源中加载动态路由信息
routesMap.putAll(loadDynamicRoute());
// 优化一下配置
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;
}
/**
* 加载路由配置,由子类去实现
*/
public abstract Map<String, ZuulRoute> loadDynamicRoute();
}
Поскольку данные динамической маршрутизации могут иметь множество видовспособ, такие как: Nacos, Redis, Zookeeper, DB и т. д., поэтому здесь определяется абстрактный класс, который определяется конкретным классом реализации
loadDynamicRouteметод
3.2 Класс реализации маршрутизации Nacos
Класс NacosDynRouteLocatorПолную реализацию кода можно посмотреть:NacosDynRouteLocator.java
3.2.1. РеализацияloadDynamicRouteметод получения динамических данных
@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() {
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);
}
3.2.2 ДополнениеNacosListenerМониторинг изменений данных маршрутизации
private void addListener() {
try {
nacosConfigProperties.configServiceInstance().addListener(ZUUL_DATA_ID, ZUUL_GROUP_ID, new Listener() {
@Override
public Executor getExecutor() {
return null;
}
@Override
public void receiveConfigInfo(String configInfo) {
//赋值路由信息
locator.setZuulRouteEntities(getListByStr(configInfo));
RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(locator);
publisher.publishEvent(routesRefreshedEvent);
}
});
} catch (NacosException e) {
log.error("nacos-addListener-error", e);
}
}
УведомлениеПосле изменения маршрутных данных вам не нужно вручную обновлять маршрут самостоятельно, вам нужно только дать
zuulОтправитьRoutesRefreshedEventмероприятие,zuulсобственныйZuulRefreshListener类Будет слушать события, чтобы помочь нам обновить маршрут
3.3 Создание класса конфигурацииNacosDynRouteLocatorБин
DynamicZuulRouteConfigМожет просматривать:NacosDynRouteLocator.java
@Configuration
@ConditionalOnProperty(prefix = "zlt.gateway.dynamicRoute", name = "enabled", havingValue = "true")
public class DynamicZuulRouteConfig {
@Autowired
private ZuulProperties zuulProperties;
@Autowired
private DispatcherServletPath dispatcherServletPath;
/**
* Nacos实现方式
*/
@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() {
return new NacosDynRouteLocator(nacosConfigProperties, publisher, dispatcherServletPath.getPrefix(), zuulProperties);
}
}
}
Здесь через пользовательскую конфигурацию, чтобы контролировать, открывать ли
动态路由功能
3.4. ДобавитьNacosконфигурация маршрутизации
- Идентификатор данных: zuul-routes
- Группа: ZUUL_GATEWAY
- Содержание конфигурации:
[
{
"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/"
}
]
Добавьте два маршрутных данных
4. Тест
-
Запустите шлюз через
/actuator/routesКонечные точки просматривают текущую информацию о маршрутизации
Вы можете видеть статические маршруты и
NacosДве информации о маршрутизации, настроенные в файле, отображаются рядом.
-
Исправлять
Nacosнастроить, закрытьcsdnмаршрутизация -
Обновите, чтобы просмотреть информацию о маршрутизации шлюза.
csdnМаршрут больше не виден, а конфигурация маршрутизации динамически изменяется.
Рекомендуемое чтение
- Трудно устранить проблемы с журналом? Трассировка ссылок распределенного журнала, чтобы помочь вам
- zuul интегрирует новейшие компоненты Sentinel для управления потоком данных
- План развертывания производства Nacos в регистрационном центре Али
- Пользовательские элементы конфигурации Spring Boot реализуют автоматические подсказки в среде IDE.
Пожалуйста, отсканируйте код, чтобы подписаться на мой официальный аккаунт