Description
All four shenyu-registry instance-register implementations (consul/etcd/zookeeper/apollo) store the cached instance list (watcherInstanceRegisterMap) in a plain java.util.HashMap. This map is written by an async watcher/callback thread (Consul scheduled executor, etcd Watch.listener, Curator CuratorWatcher, Apollo ConfigChangeListener) while concurrently read and written by the caller thread in selectInstances (containsKey/get/put). The Zookeeper impl also races nodeDataMap between persistInstance (caller) and the ConnectionState.RECONNECTED listener; Apollo additionally mutates a local HashMap childrenList from the config thread. The Nacos impl already uses ConcurrentHashMap/ConcurrentMap.
Location
shenyu-registry/shenyu-registry-consul/src/main/java/org/apache/shenyu/registry/consul/ConsulInstanceRegisterRepository.java:76,90,92,160-196 (also consulIndexes:76, watchSelectKeySet:92)
shenyu-registry/shenyu-registry-etcd/.../EtcdInstanceRegisterRepository.java:60,98,118-121
shenyu-registry/shenyu-registry-zookeeper/.../ZookeeperInstanceRegisterRepository.java:67,71,100,122,145-167
shenyu-registry/shenyu-registry-apollo/.../ApolloInstanceRegisterRepository.java:65,128-163
Impact
Under normal multi-path operation, concurrent access corrupts the HashMap, loses instance updates (watcher misses instances or serves stale lists), produces inconsistent discovery state, or causes infinite-loop/CME-style hangs on the selectInstances path → wrong/missing upstream routing.
Suggested fix
Replace all new HashMap<>() / new HashSet<>() field declarations with Maps.newConcurrentMap() / ConcurrentHashMap.newKeySet() (as the Nacos impl already does), or guard all access with a single synchronized lock. For the Apollo local childrenList, use ConcurrentHashMap or copy before passing to the listener.
Related existing
Distinct from SYNC-8 (#6783, ConsulSyncDataService HashMap) — that covers shenyu-sync-data-center/shenyu-sync-data-consul (gateway-side sync service), not shenyu-registry-consul (instance register repository). The Nacos registry is already safe.
Description
All four
shenyu-registryinstance-register implementations (consul/etcd/zookeeper/apollo) store the cached instance list (watcherInstanceRegisterMap) in a plainjava.util.HashMap. This map is written by an async watcher/callback thread (Consul scheduled executor, etcdWatch.listener, CuratorCuratorWatcher, ApolloConfigChangeListener) while concurrently read and written by the caller thread inselectInstances(containsKey/get/put). The Zookeeper impl also racesnodeDataMapbetweenpersistInstance(caller) and theConnectionState.RECONNECTEDlistener; Apollo additionally mutates a localHashMap childrenListfrom the config thread. The Nacos impl already usesConcurrentHashMap/ConcurrentMap.Location
shenyu-registry/shenyu-registry-consul/src/main/java/org/apache/shenyu/registry/consul/ConsulInstanceRegisterRepository.java:76,90,92,160-196(alsoconsulIndexes:76,watchSelectKeySet:92)shenyu-registry/shenyu-registry-etcd/.../EtcdInstanceRegisterRepository.java:60,98,118-121shenyu-registry/shenyu-registry-zookeeper/.../ZookeeperInstanceRegisterRepository.java:67,71,100,122,145-167shenyu-registry/shenyu-registry-apollo/.../ApolloInstanceRegisterRepository.java:65,128-163Impact
Under normal multi-path operation, concurrent access corrupts the HashMap, loses instance updates (watcher misses instances or serves stale lists), produces inconsistent discovery state, or causes infinite-loop/CME-style hangs on the
selectInstancespath → wrong/missing upstream routing.Suggested fix
Replace all
new HashMap<>()/new HashSet<>()field declarations withMaps.newConcurrentMap()/ConcurrentHashMap.newKeySet()(as the Nacos impl already does), or guard all access with a singlesynchronizedlock. For the Apollo localchildrenList, useConcurrentHashMapor copy before passing to the listener.Related existing
Distinct from SYNC-8 (#6783,
ConsulSyncDataServiceHashMap) — that coversshenyu-sync-data-center/shenyu-sync-data-consul(gateway-side sync service), notshenyu-registry-consul(instance register repository). The Nacos registry is already safe.