Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify the compatibility of label routing when upgrading from 1.0-1.3 #1424

Merged
merged 1 commit into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion sermant-plugins/sermant-router/config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ router.plugin:
request-tags: []
# 需要解析的请求头的tag
parse-header-tag: ''
# 是否初始化dubbo区域路由,兼容性开关,开启后,会在dubbo的配置缓存中初始化一条以zone匹配的同标签路由
enabled-dubbo-zone-router: false
# 是否初始化spring cloud区域路由,兼容性开关,开启后,会在spring cloud的配置缓存中初始化一条以zone匹配的同标签路由
enabled-spring-zone-router: false
transmit.plugin:
# 是否在直接new Thread时传递标签
enabled-thread: true
# 是否在非定时线程池中传递标签
enabled-thread-pool: true
# 是否在定时线程池的schedule/scheduleAtFixedRate/scheduleWithFixedDelay方法中传递标签
enabled-scheduler: true
enabled-scheduler: false
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ public class RouterConfig implements PluginConfig {
*/
private String zone;

/**
* 是否初始化dubbo区域路由,兼容性开关,开启后,会在dubbo的配置缓存中初始化一条以zone匹配的同标签路由
*/
@ConfigFieldKey("enabled-dubbo-zone-router")
private boolean enabledDubboZoneRouter;

/**
* 是否初始化spring cloud区域路由,兼容性开关,开启后,会在spring cloud的配置缓存中初始化一条以zone匹配的同标签路由
*/
@ConfigFieldKey("enabled-spring-zone-router")
private boolean enabledSpringZoneRouter;

/**
* 是否适配注册插件
*/
Expand Down Expand Up @@ -104,6 +116,22 @@ public void setZone(String zone) {
this.zone = zone;
}

public boolean isEnabledDubboZoneRouter() {
return enabledDubboZoneRouter;
}

public void setEnabledDubboZoneRouter(boolean enabledDubboZoneRouter) {
this.enabledDubboZoneRouter = enabledDubboZoneRouter;
}

public boolean isEnabledSpringZoneRouter() {
return enabledSpringZoneRouter;
}

public void setEnabledSpringZoneRouter(boolean enabledSpringZoneRouter) {
this.enabledSpringZoneRouter = enabledSpringZoneRouter;
}

public boolean isEnabledRegistryPluginAdaptation() {
return enabledRegistryPluginAdaptation;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ public class RouterConstant {
public static final String IS_METHOD_SUFFIX = "()";

/**
* 标签路由key前缀
* 流量路由key前缀
*/
public static final String ROUTER_KEY_PREFIX = "servicecomb.routeRule";

/**
* 标签路由全局规则key
* 流量路由全局规则key
*/
public static final String GLOBAL_ROUTER_KEY = "servicecomb.globalRouteRule";

Expand Down Expand Up @@ -156,6 +156,38 @@ public class RouterConstant {
*/
public static final String ZONE = "zone";

/**
* 标签路由key前缀
*/
public static final String TAG_KEY_PREFIX = "servicecomb.tagRule";

/**
* 标签路由全局规则key
*/
public static final String GLOBAL_TAG_KEY = "servicecomb.globalTagRule";

/**
* 泳道key前缀
*/
public static final String LANE_KEY_PREFIX = "servicecomb.laneRule";

/**
* 泳道全局规则key
*/
public static final String GLOBAL_LANE_KEY = "servicecomb.globalLaneRule";

/**
* 全量服务级兼容的key
*/
public static final List<String> COMPATIBILITY_KEY_LIST = Arrays.asList(ROUTER_KEY_PREFIX, TAG_KEY_PREFIX,
LANE_KEY_PREFIX);

/**
* 全局级兼容的key
*/
public static final List<String> GLOBAL_COMPATIBILITY_KEY_LIST = Arrays.asList(GLOBAL_ROUTER_KEY, GLOBAL_TAG_KEY,
GLOBAL_LANE_KEY);

private RouterConstant() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,20 @@ public void updateServiceRule(String serviceName, List<EntireRule> entireRules)
}
}

/**
* 按类型更新服务粒度的路由规则
*
* @param serviceName 服务名
* @param entireRule 规则
*/
public void updateServiceRule(String serviceName, EntireRule entireRule) {
Map<String, List<Rule>> ruleList = rules.computeIfAbsent(entireRule.getKind(),
key -> new ConcurrentHashMap<>());
ruleList.put(serviceName, entireRule.getRules());
LOGGER.info(String.format(Locale.ROOT, "Rule for %s has been updated: %s ", serviceName,
JSONObject.toJSONString(entireRule)));
}

/**
* 移除服务的路由规则
*
Expand All @@ -123,6 +137,20 @@ public void removeServiceRule(String serviceName) {
LOGGER.info(String.format(Locale.ROOT, "All rules for %s have been removed! ", serviceName));
}

/**
* 移除服务的路由规则
*
* @param serviceName 服务名
* @param kind 规则类型
*/
public void removeServiceRule(String serviceName, String kind) {
Map<String, List<Rule>> ruleList = rules.get(kind);
if (!CollectionUtils.isEmpty(ruleList)) {
ruleList.remove(serviceName);
}
LOGGER.info(String.format(Locale.ROOT, "%s rules for %s have been removed! ", kind, serviceName));
}

/**
* 重置路由规则
*
Expand All @@ -139,6 +167,29 @@ public void resetRouteRule(Map<String, List<EntireRule>> map) {
}
}

/**
* 重置路由规则
*
* @param kind 规则类型
* @param map 路由规则
*/
public void resetRouteRule(String kind, Map<String, EntireRule> map) {
if (map == null) {
return;
}
if (map.isEmpty()) {
rules.remove(kind);
} else {
for (Map.Entry<String, EntireRule> ruleEntry : map.entrySet()) {
EntireRule entireRule = ruleEntry.getValue();
Map<String, List<Rule>> serviceRuleMap = rules.compute(kind, (key, value) -> new ConcurrentHashMap<>());
serviceRuleMap.put(ruleEntry.getKey(), entireRule.getRules());
}
}
LOGGER.info(String.format(Locale.ROOT, "Service rules have been updated: %s",
JSONObject.toJSONString(map)));
}

/**
* 重置全局路由规则
*
Expand All @@ -153,6 +204,25 @@ public void resetGlobalRule(List<EntireRule> list) {
JSONObject.toJSONString(list)));
}

/**
* 重置全局路由规则
*
* @param entireRule 路由规则
*/
public void resetGlobalRule(EntireRule entireRule) {
List<Rule> ruleList = entireRule.getRules();
if (ruleList == null) {
return;
}
if (ruleList.isEmpty()) {
globalRules.remove(entireRule.getKind());
} else {
globalRules.put(entireRule.getKind(), ruleList);
}
LOGGER.info(String.format(Locale.ROOT, "Global rules have been updated: %s",
JSONObject.toJSONString(entireRule)));
}

/**
* 路由规则是否无效
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,59 +258,71 @@ public static void removeInvalidRules(List<EntireRule> list, boolean isReplaceDa
entireIterator.remove();
continue;
}
removeInvalidRules(entireRule.getKind(), entireRule.getRules(), isReplaceDash, isAppendPrefix);

Iterator<Rule> ruleIterator = entireRule.getRules().iterator();
while (ruleIterator.hasNext()) {
Rule rule = ruleIterator.next();
List<Route> routes = rule.getRoute();
// 去掉全是无效规则的配置
if (CollectionUtils.isEmpty(entireRule.getRules())) {
entireIterator.remove();
}
}
}

// 去掉没有配置路由的规则
if (CollectionUtils.isEmpty(routes)) {
LOGGER.warning("Routes are empty, rule will be removed.");
ruleIterator.remove();
continue;
}
/**
* 去掉无效的规则
*
* @param kind 规则类型
* @param rules 规则
* @param isReplaceDash 是否需要把"-"替换成"."
* @param isAppendPrefix 元数据的key值是否需要加上前缀
*/
public static void removeInvalidRules(String kind, List<Rule> rules, boolean isReplaceDash,
boolean isAppendPrefix) {
Iterator<Rule> ruleIterator = rules.iterator();
while (ruleIterator.hasNext()) {
Rule rule = ruleIterator.next();
List<Route> routes = rule.getRoute();

// 去掉无效的路由和修复同标签规则的路由
removeInvalidRoute(routes, kind, isReplaceDash, isAppendPrefix);
// 去掉没有配置路由的规则
if (CollectionUtils.isEmpty(routes)) {
LOGGER.warning("Routes are empty, rule will be removed.");
ruleIterator.remove();
continue;
}

List<Route> fallback = rule.getFallback();
if (!CollectionUtils.isEmpty(fallback)) {
// 去掉无效的fallback路由和修复同标签规则的fallback路由
removeInvalidRoute(fallback, kind, isReplaceDash, isAppendPrefix);
}
// 去掉无效的路由和修复同标签规则的路由
removeInvalidRoute(routes, kind, isReplaceDash, isAppendPrefix);

// 去掉全是无效路由的规则
if (CollectionUtils.isEmpty(routes)) {
LOGGER.warning("Routes are invalid, rule will be removed.");
ruleIterator.remove();
continue;
}
List<Route> fallback = rule.getFallback();
if (!CollectionUtils.isEmpty(fallback)) {
// 去掉无效的fallback路由和修复同标签规则的fallback路由
removeInvalidRoute(fallback, kind, isReplaceDash, isAppendPrefix);
}

if (RouterConstant.FLOW_MATCH_KIND.equals(kind)) {
// 去掉无效的规则
removeInvalidMatch(rule.getMatch());
// 去掉全是无效路由的规则
if (CollectionUtils.isEmpty(routes)) {
LOGGER.warning("Routes are invalid, rule will be removed.");
ruleIterator.remove();
continue;
}

// 无attachments规则,将headers规则更新到attachments规则
setAttachmentsByHeaders(rule.getMatch());
continue;
}
if (RouterConstant.FLOW_MATCH_KIND.equals(kind)) {
// 去掉无效的规则
removeInvalidMatch(rule.getMatch());

if (RouterConstant.TAG_MATCH_KIND.equals(kind)) {
// 去掉无效的规则
removeInvalidTagMatch(rule.getMatch(), isAppendPrefix);
continue;
}
// 无attachments规则,将headers规则更新到attachments规则
setAttachmentsByHeaders(rule.getMatch());
continue;
}

if (RouterConstant.LANE_MATCH_KIND.equals(kind)) {
// 去掉无效的规则
removeInvalidLaneMatch(rule.getMatch());
}
if (RouterConstant.TAG_MATCH_KIND.equals(kind)) {
// 去掉无效的规则
removeInvalidTagMatch(rule.getMatch(), isAppendPrefix);
continue;
}

// 去掉全是无效规则的配置
if (CollectionUtils.isEmpty(entireRule.getRules())) {
entireIterator.remove();
if (RouterConstant.LANE_MATCH_KIND.equals(kind)) {
// 去掉无效的规则
removeInvalidLaneMatch(rule.getMatch());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package com.huaweicloud.sermant.router.config.handler;

import com.huaweicloud.sermant.core.service.dynamicconfig.common.DynamicConfigEvent;
import com.huaweicloud.sermant.router.common.constants.RouterConstant;
import com.huaweicloud.sermant.router.config.common.SafeConstructor;

import org.yaml.snakeyaml.Yaml;
Expand All @@ -27,7 +27,7 @@
* @author provenceee
* @since 2022-08-09
*/
public abstract class AbstractConfigHandler {
public abstract class AbstractConfigHandler implements AbstractHandler {
/**
* yaml
*/
Expand All @@ -40,19 +40,15 @@ public AbstractConfigHandler() {
this.yaml = new Yaml(new SafeConstructor(null));
}

/**
* 路由配置处理
*
* @param event 配置监听事件
* @param cacheName 缓存名
*/
public abstract void handle(DynamicConfigEvent event, String cacheName);

/**
* 是否需要处理
*
* @param key 配置key
* @param content 配置内容
* @return 是否需要处理
*/
public abstract boolean shouldHandle(String key);
@Override
public boolean shouldHandle(String key, String content) {
return RouterConstant.MATCH_KIND_LIST.stream().anyMatch(content::contains);
}
}
Loading