From 716cbcf4c045799a118404901001dcc07d69bc0d Mon Sep 17 00:00:00 2001 From: chengyouling Date: Sat, 24 Jan 2026 10:37:58 +0800 Subject: [PATCH 1/7] [#5061] fixed service upgrade caused memory leak problem. --- .../org/apache/servicecomb/registry/swagger/SwaggerLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java index 6c49ae44208..e43d875cfd3 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java @@ -181,7 +181,7 @@ private Swagger loadFromResource(String path) { private Swagger loadFromRemote(Microservice microservice, Collection instances, String schemaId) { - String key = microservice.getServiceId() + "." + schemaId; + String key = microservice.getServiceName() + "." + schemaId; Swagger result = remoteSwagger.computeIfAbsent(key, k -> { String schemaContent = DiscoveryManager.INSTANCE.getSchema(microservice.getServiceId(), instances, schemaId); if (schemaContent != null) { From fe6d2a8cedf4d4146d72cfa0f9033bda6e61dfaf Mon Sep 17 00:00:00 2001 From: chengyouling Date: Thu, 29 Jan 2026 10:50:43 +0800 Subject: [PATCH 2/7] remove remoteSwagger --- .../definition/ServiceRegistryListener.java | 7 +++++++ .../registry/swagger/SwaggerLoader.java | 17 +++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/apache/servicecomb/core/definition/ServiceRegistryListener.java b/core/src/main/java/org/apache/servicecomb/core/definition/ServiceRegistryListener.java index 696199b64fc..211e70a91f1 100644 --- a/core/src/main/java/org/apache/servicecomb/core/definition/ServiceRegistryListener.java +++ b/core/src/main/java/org/apache/servicecomb/core/definition/ServiceRegistryListener.java @@ -130,6 +130,13 @@ public void onCreateMicroserviceVersion(CreateMicroserviceVersionEvent event) { microserviceVersion.getVendorExtensions().put(CORE_MICROSERVICE_META, microserviceMeta); } + @EnableExceptionPropagation + @SubscriberOrder(-800) + @Subscribe + public void onDestroyMicroserviceEvent(DestroyMicroserviceEvent event) { + scbEngine.getSwaggerLoader().removeRemoteSwagger(event.getMicroserviceVersions().getInstances()); + } + public void destroy() { scbEngine.getEventBus().unregister(this); } diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java index e43d875cfd3..3fbd417d3ec 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java @@ -37,6 +37,7 @@ import org.apache.servicecomb.swagger.generator.SwaggerGenerator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.util.CollectionUtils; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Charsets; @@ -181,7 +182,7 @@ private Swagger loadFromResource(String path) { private Swagger loadFromRemote(Microservice microservice, Collection instances, String schemaId) { - String key = microservice.getServiceName() + "." + schemaId; + String key = microservice.getServiceId() + "." + schemaId; Swagger result = remoteSwagger.computeIfAbsent(key, k -> { String schemaContent = DiscoveryManager.INSTANCE.getSchema(microservice.getServiceId(), instances, schemaId); if (schemaContent != null) { @@ -197,7 +198,8 @@ private Swagger loadFromRemote(Microservice microservice, Collection instances) { + if (CollectionUtils.isEmpty(instances)) { + return; + } + String serviceId = instances.get(0).getServiceId(); + int originSize = remoteSwagger.size(); + remoteSwagger.remove(serviceId); + LOGGER.info( + "remove [{}] swagger, origin size [{}], current size [{}]", serviceId, originSize, remoteSwagger.size()); + } } From 0568d6813571907fb5a40b7f0c84c315e6f01c46 Mon Sep 17 00:00:00 2001 From: chengyouling Date: Thu, 29 Jan 2026 17:59:47 +0800 Subject: [PATCH 3/7] add remoteSwaggerEvent --- .../definition/ServiceRegistryListener.java | 13 +++--- .../api/event/RefreshRemoteSwaggerEvent.java | 46 +++++++++++++++++++ .../consumer/MicroserviceVersions.java | 22 +++++++++ .../registry/swagger/SwaggerLoader.java | 25 +++++++--- 4 files changed, 93 insertions(+), 13 deletions(-) create mode 100644 foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/event/RefreshRemoteSwaggerEvent.java diff --git a/core/src/main/java/org/apache/servicecomb/core/definition/ServiceRegistryListener.java b/core/src/main/java/org/apache/servicecomb/core/definition/ServiceRegistryListener.java index 211e70a91f1..733511b73a2 100644 --- a/core/src/main/java/org/apache/servicecomb/core/definition/ServiceRegistryListener.java +++ b/core/src/main/java/org/apache/servicecomb/core/definition/ServiceRegistryListener.java @@ -29,6 +29,7 @@ import org.apache.servicecomb.registry.api.event.CreateMicroserviceEvent; import org.apache.servicecomb.registry.api.event.CreateMicroserviceVersionEvent; import org.apache.servicecomb.registry.api.event.DestroyMicroserviceEvent; +import org.apache.servicecomb.registry.api.event.RefreshRemoteSwaggerEvent; import org.apache.servicecomb.registry.api.registry.Microservice; import org.apache.servicecomb.registry.consumer.MicroserviceVersion; import org.apache.servicecomb.registry.consumer.MicroserviceVersions; @@ -130,14 +131,14 @@ public void onCreateMicroserviceVersion(CreateMicroserviceVersionEvent event) { microserviceVersion.getVendorExtensions().put(CORE_MICROSERVICE_META, microserviceMeta); } + public void destroy() { + scbEngine.getEventBus().unregister(this); + } + @EnableExceptionPropagation @SubscriberOrder(-800) @Subscribe - public void onDestroyMicroserviceEvent(DestroyMicroserviceEvent event) { - scbEngine.getSwaggerLoader().removeRemoteSwagger(event.getMicroserviceVersions().getInstances()); - } - - public void destroy() { - scbEngine.getEventBus().unregister(this); + public void onRefreshRemoteSwaggerEvent(RefreshRemoteSwaggerEvent event) { + scbEngine.getSwaggerLoader().removeRemoteSwagger(event); } } diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/event/RefreshRemoteSwaggerEvent.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/event/RefreshRemoteSwaggerEvent.java new file mode 100644 index 00000000000..b8baf10ea67 --- /dev/null +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/api/event/RefreshRemoteSwaggerEvent.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.servicecomb.registry.api.event; + +import java.util.List; + +public class RefreshRemoteSwaggerEvent { + private final List serviceIds; + + private final String appId; + + private final String serviceName; + + public RefreshRemoteSwaggerEvent(List serviceIds, String appId, String serviceName) { + this.serviceIds = serviceIds; + this.appId = appId; + this.serviceName = serviceName; + } + + public List getServiceIds() { + return serviceIds; + } + + public String getAppId() { + return appId; + } + + public String getServiceName() { + return serviceName; + } +} diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/consumer/MicroserviceVersions.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/consumer/MicroserviceVersions.java index c84925a4783..c44e319e8d0 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/consumer/MicroserviceVersions.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/consumer/MicroserviceVersions.java @@ -33,6 +33,7 @@ import org.apache.servicecomb.registry.api.event.CreateMicroserviceEvent; import org.apache.servicecomb.registry.api.event.DestroyMicroserviceEvent; import org.apache.servicecomb.registry.api.event.MicroserviceInstanceChangedEvent; +import org.apache.servicecomb.registry.api.event.RefreshRemoteSwaggerEvent; import org.apache.servicecomb.registry.api.registry.MicroserviceInstance; import org.apache.servicecomb.registry.api.registry.MicroserviceInstanceStatus; import org.apache.servicecomb.registry.api.registry.MicroserviceInstances; @@ -41,8 +42,10 @@ import org.apache.servicecomb.registry.definition.MicroserviceNameParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.util.CollectionUtils; import com.google.common.annotations.VisibleForTesting; +import com.netflix.config.DynamicPropertyFactory; public class MicroserviceVersions { private static final Logger LOGGER = LoggerFactory.getLogger(MicroserviceVersions.class); @@ -183,6 +186,9 @@ public void pullInstances() { return; } + // send refresh remote swagger info + sendRefreshRemoteSwaggerEvent(); + pulledInstances = microserviceInstances.getInstancesResponse().getInstances(); pulledInstances.sort(Comparator.comparing(MicroserviceInstance::getInstanceId)); String rev = microserviceInstances.getRevision(); @@ -190,6 +196,22 @@ public void pullInstances() { safeSetInstances(pulledInstances, rev); } + private void sendRefreshRemoteSwaggerEvent() { + boolean refreshEnabled = DynamicPropertyFactory.getInstance() + .getBooleanProperty("servicecomb.remote.swagger.refresh.enabled", false).get(); + if (!refreshEnabled) { + return; + } + List serviceIds = new ArrayList<>(); + if (CollectionUtils.isEmpty(pulledInstances)) { + return; + } + for (MicroserviceInstance instance : pulledInstances) { + serviceIds.add(instance.getServiceId()); + } + appManager.getEventBus().post(new RefreshRemoteSwaggerEvent(serviceIds, appId, shortName)); + } + protected MicroserviceInstances findServiceInstances() { return DiscoveryManager.INSTANCE.findServiceInstances(appId, shortName, diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java index 3fbd417d3ec..d74d4251fb3 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; import org.apache.commons.io.FilenameUtils; import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx; @@ -30,6 +31,7 @@ import org.apache.servicecomb.foundation.common.utils.ResourceUtil; import org.apache.servicecomb.registry.DiscoveryManager; import org.apache.servicecomb.registry.RegistrationManager; +import org.apache.servicecomb.registry.api.event.RefreshRemoteSwaggerEvent; import org.apache.servicecomb.registry.api.registry.Microservice; import org.apache.servicecomb.registry.api.registry.MicroserviceInstance; import org.apache.servicecomb.registry.definition.MicroserviceNameParser; @@ -215,14 +217,23 @@ private Swagger loadFromRemote(Microservice microservice, Collection instances) { - if (CollectionUtils.isEmpty(instances)) { + public void removeRemoteSwagger(RefreshRemoteSwaggerEvent event) { + List serviceIds = event.getServiceIds(); + if (CollectionUtils.isEmpty(serviceIds)) { return; } - String serviceId = instances.get(0).getServiceId(); - int originSize = remoteSwagger.size(); - remoteSwagger.remove(serviceId); - LOGGER.info( - "remove [{}] swagger, origin size [{}], current size [{}]", serviceId, originSize, remoteSwagger.size()); + List matchKey = remoteSwagger.keySet().stream().filter(key -> { + for (String serviceId : serviceIds) { + if (key.startsWith(serviceId)) { + return true; + } + } + return false; + }).toList(); + for (String key : matchKey) { + remoteSwagger.remove(key); + LOGGER.info("remove local appid=[{}], serviceName=[{}], swagger [{}]", event.getAppId(), + event.getServiceName(), key); + } } } From f5ff0c5ddf19cabb0597a2307ee1195dc578caac Mon Sep 17 00:00:00 2001 From: chengyouling Date: Thu, 29 Jan 2026 18:11:07 +0800 Subject: [PATCH 4/7] remove import --- .../org/apache/servicecomb/registry/swagger/SwaggerLoader.java | 1 - 1 file changed, 1 deletion(-) diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java index d74d4251fb3..b61d0fc397b 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; import org.apache.commons.io.FilenameUtils; import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx; From 260ad1445548a2bd533c2894e334d6a47cf35f17 Mon Sep 17 00:00:00 2001 From: chengyouling Date: Fri, 30 Jan 2026 09:40:52 +0800 Subject: [PATCH 5/7] remove log --- .../org/apache/servicecomb/registry/swagger/SwaggerLoader.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java index b61d0fc397b..c0553e9da42 100644 --- a/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java +++ b/foundations/foundation-registry/src/main/java/org/apache/servicecomb/registry/swagger/SwaggerLoader.java @@ -199,8 +199,6 @@ private Swagger loadFromRemote(Microservice microservice, Collection Date: Fri, 30 Jan 2026 16:02:27 +0800 Subject: [PATCH 6/7] set jdk version --- .github/workflows/unit-test-jdk17.yml | 2 +- .github/workflows/unit-test-jdk21.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/unit-test-jdk17.yml b/.github/workflows/unit-test-jdk17.yml index 1e66fae5368..ebc920c237a 100644 --- a/.github/workflows/unit-test-jdk17.yml +++ b/.github/workflows/unit-test-jdk17.yml @@ -33,7 +33,7 @@ jobs: - name: Set up jdk uses: actions/setup-java@v3 with: - java-version: '17' + java-version: '17.0.2' distribution: 'temurin' - name: Compilation and Installation run: mvn -B -Dcheckstyle.skip -Dspotbugs.skip=true clean install -Pit diff --git a/.github/workflows/unit-test-jdk21.yml b/.github/workflows/unit-test-jdk21.yml index 0f83cf44428..96c73067bcb 100644 --- a/.github/workflows/unit-test-jdk21.yml +++ b/.github/workflows/unit-test-jdk21.yml @@ -33,7 +33,7 @@ jobs: - name: Set up jdk uses: actions/setup-java@v3 with: - java-version: '21' + java-version: '21.0.7' distribution: 'temurin' - name: Compilation and Installation run: mvn -B -Dcheckstyle.skip -Dspotbugs.skip=true clean install -Pit \ No newline at end of file From 0c11ade24461b68ce7619df57a238289ebea96d9 Mon Sep 17 00:00:00 2001 From: chengyouling Date: Fri, 30 Jan 2026 16:04:29 +0800 Subject: [PATCH 7/7] set jdk version --- .github/workflows/maven.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 5788af888b0..d566e7e2728 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -36,7 +36,7 @@ jobs: - name: Set up jdk uses: actions/setup-java@v3 with: - java-version: '17' + java-version: '17.0.2' distribution: 'temurin' - name: Set up Maven uses: stCarolas/setup-maven@v4.5