From 145b33c0c1334d8e69807a218cb9e156a3e96424 Mon Sep 17 00:00:00 2001 From: ggbocoder <119659920+ggbocoder@users.noreply.github.com> Date: Fri, 6 Sep 2024 15:21:38 +0800 Subject: [PATCH] bugfix: fix namingserver changVgroup failed (#6817) --- changes/en-us/2.x.md | 3 ++- changes/zh-cn/2.x.md | 1 + .../namingserver/entity/bo/NamespaceBO.java | 7 +++++- .../namingserver/manager/NamingManager.java | 22 ++++++++++--------- .../controller/VGroupMappingController.java | 4 ---- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md index a09f52ad979..9093aed1db7 100644 --- a/changes/en-us/2.x.md +++ b/changes/en-us/2.x.md @@ -33,7 +33,8 @@ Add changes here for all PR submitted to the 2.x branch. - [[#6797](https://github.com/apache/incubator-seata/pull/6797)] fall back to any of available cluster address when query cluster address is empty - [[#6800](https://github.com/apache/incubator-seata/pull/6800)] make exception message generic for all database drivers - [[#6759](https://github.com/apache/incubator-seata/pull/6759)] fix the error of active refresh failure of cross-database table metadata -- [[#6812](https://github.com/apache/incubator-seata/pull/6812)] change group and node offline status are not pushed in real time +- [[#6812](https://github.com/apache/incubator-seata/pull/6812)] bugfix: change group and node offline status are not pushed in real time +- [[#6817](https://github.com/apache/incubator-seata/pull/6817)] bugfix: fix namingserver changVgroup failed - [[#6820](https://github.com/apache/incubator-seata/pull/6820)] Fix file path error in the Dockerfile diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md index ab20393b222..850f1d7ea74 100644 --- a/changes/zh-cn/2.x.md +++ b/changes/zh-cn/2.x.md @@ -35,6 +35,7 @@ - [[#6800](https://github.com/apache/incubator-seata/pull/6800)] 使异常消息对所有数据库驱动程序通用 - [[#6812](https://github.com/apache/incubator-seata/pull/6812)] 修复切换事务分组和节点下线时namingserver没有实时感知和推送的bug - [[#6759](https://github.com/apache/incubator-seata/pull/6759)] 修复跨库表主动刷新`tableMeta`的异常问题 +- [[#6817](https://github.com/apache/incubator-seata/pull/6817)] 修复namingserver切换事务分组失效的问题 - [[#6820](https://github.com/apache/incubator-seata/pull/6820)] 修复Dockerfile得文件结构错误 - ### optimize: diff --git a/namingserver/src/main/java/org/apache/seata/namingserver/entity/bo/NamespaceBO.java b/namingserver/src/main/java/org/apache/seata/namingserver/entity/bo/NamespaceBO.java index 74749d8aac2..e5694b02403 100644 --- a/namingserver/src/main/java/org/apache/seata/namingserver/entity/bo/NamespaceBO.java +++ b/namingserver/src/main/java/org/apache/seata/namingserver/entity/bo/NamespaceBO.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.seata.common.metadata.Cluster; @@ -56,7 +57,11 @@ public ClusterBO getCluster(String clusterName) { } public void removeOldCluster(String clusterName) { - clusterMap.keySet().forEach(currentClusterName -> { + Set clusterSet = clusterMap.keySet(); + if (clusterSet.size() <= 1) { + return; + } + clusterSet.forEach(currentClusterName -> { if (!StringUtils.equals(currentClusterName, clusterName)) { clusterMap.remove(currentClusterName); } diff --git a/namingserver/src/main/java/org/apache/seata/namingserver/manager/NamingManager.java b/namingserver/src/main/java/org/apache/seata/namingserver/manager/NamingManager.java index 20e2d3dc049..9a6b790220d 100644 --- a/namingserver/src/main/java/org/apache/seata/namingserver/manager/NamingManager.java +++ b/namingserver/src/main/java/org/apache/seata/namingserver/manager/NamingManager.java @@ -205,28 +205,29 @@ public Result removeGroup(Unit unit, String vGroup, String clusterName, return new Result<>("200", "remove group in old cluster successfully!"); } - public void addGroup(String namespace, String clusterName, String unitName, String vGroup) { + public boolean addGroup(String namespace, String clusterName, String unitName, String vGroup) { try { ClusterBO clusterBO = vGroupMap.get(vGroup, k -> new ConcurrentHashMap<>()) .computeIfAbsent(namespace, k -> new NamespaceBO()).getCluster(clusterName); - if (clusterBO != null && !clusterBO.getUnitNames().contains(unitName)) { - clusterBO.addUnit(unitName); + if (clusterBO != null /**&& !clusterBO.getUnitNames().contains(unitName)**/) { + boolean needNotify = !clusterBO.getUnitNames().contains(unitName); NamespaceBO namespaceBO = vGroupMap.getIfPresent(vGroup).get(namespace); namespaceBO.removeOldCluster(clusterName); - applicationContext.publishEvent(new ClusterChangeEvent(this, vGroup, System.currentTimeMillis())); + if (needNotify) { + clusterBO.addUnit(unitName); + } + return needNotify; } } catch (Exception e) { LOGGER.error("change vGroup mapping failed:{}", vGroup, e); } + return false; } public void notifyClusterChange(String vGroup, String namespace, String clusterName, String unitName, long term) { Optional.ofNullable(vGroupMap.asMap().get(vGroup)).flatMap(map -> Optional.ofNullable(map.get(namespace)).flatMap(namespaceBO -> Optional.ofNullable(namespaceBO.getCluster(clusterName)))).ifPresent(clusterBO -> { -// Set units = clusterBO.getUnitNames(); -// if (!CollectionUtils.isEmpty(units)) { applicationContext.publishEvent(new ClusterChangeEvent(this, vGroup, term)); -// } }); } @@ -248,8 +249,8 @@ public boolean registerInstance(NamingServerNode node, String namespace, String vGroups.forEach((k, v) -> { // In non-raft mode, a unit is one-to-one with a node, and the unitName is stored on the node. // In raft mode, the unitName is equal to the raft-group, so the node's unitName cannot be used. - addGroup(namespace, clusterName, StringUtils.isBlank(v) ? unitName : v, k); - if (hasChanged) { + boolean changed = addGroup(namespace, clusterName, StringUtils.isBlank(v) ? unitName : v, k); + if (hasChanged || changed) { notifyClusterChange(k, namespace, clusterName, unitName, node.getTerm()); } }); @@ -360,6 +361,7 @@ public void instanceHeartBeatCheck() { } public Result changeGroup(String namespace, String vGroup, String clusterName, String unitName) { + long changeTime = System.currentTimeMillis(); ConcurrentMap namespaceMap = new ConcurrentHashMap<>(vGroupMap.get(vGroup)); Set currentNamespaces = namespaceMap.keySet(); Map> namespaceClusters = new HashMap<>(); @@ -384,7 +386,7 @@ public Result changeGroup(String namespace, String vGroup, String cluste String unit = optionalEntry.get().getKey(); Unit unitData = optionalEntry.get().getValue(); result.set(removeGroup(unitData, vGroup, cluster, oldNamespace, unitName)); - notifyClusterChange(vGroup, namespace, cluster, unit, -1); + notifyClusterChange(vGroup, namespace, cluster, unit, changeTime); } } }); diff --git a/server/src/main/java/org/apache/seata/server/controller/VGroupMappingController.java b/server/src/main/java/org/apache/seata/server/controller/VGroupMappingController.java index ae80858ff10..348a7502830 100644 --- a/server/src/main/java/org/apache/seata/server/controller/VGroupMappingController.java +++ b/server/src/main/java/org/apache/seata/server/controller/VGroupMappingController.java @@ -73,8 +73,6 @@ public Result addVGroup(@RequestParam String vGroup, @RequestParam String uni result.setCode("500"); result.setMessage("add vGroup failed!"); } - // push the newest mapping relationship - vGroupMappingStoreManager.notifyMapping(); return result; } @@ -93,8 +91,6 @@ public Result removeVGroup(@RequestParam String vGroup) { result.setCode("500"); result.setMessage("remove vGroup failed!"); } - // push the newest mapping relationship - vGroupMappingStoreManager.notifyMapping(); return result; }