From 408148ac32b60b8ec0ddf9a38d3efee8da90d597 Mon Sep 17 00:00:00 2001 From: chengyouling Date: Sat, 24 Jan 2026 10:31:05 +0800 Subject: [PATCH 1/8] [#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 61e3003b10c8e9e4b03d7ccc2c6ed1999679197a Mon Sep 17 00:00:00 2001 From: chengyouling Date: Tue, 27 Jan 2026 09:56:50 +0800 Subject: [PATCH 2/8] add note description --- .../org/apache/servicecomb/registry/swagger/SwaggerLoader.java | 2 ++ 1 file changed, 2 insertions(+) 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..ad1be38e707 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,6 +181,8 @@ private Swagger loadFromResource(String path) { private Swagger loadFromRemote(Microservice microservice, Collection instances, String schemaId) { + // The client does not restart, the serviceId changes after the provider is upgraded. As a result, + // the same schema is loaded repeatedly. String key = microservice.getServiceName() + "." + schemaId; Swagger result = remoteSwagger.computeIfAbsent(key, k -> { String schemaContent = DiscoveryManager.INSTANCE.getSchema(microservice.getServiceId(), instances, schemaId); From 6024854fe161303dfb2f763de0321a979363a687 Mon Sep 17 00:00:00 2001 From: chengyouling Date: Thu, 29 Jan 2026 17:46:45 +0800 Subject: [PATCH 3/8] add remoteSwaggerEvent --- .../definition/ServiceRegistryListener.java | 8 ++++ .../api/event/RefreshRemoteSwaggerEvent.java | 46 +++++++++++++++++++ .../consumer/MicroserviceVersions.java | 22 +++++++++ .../registry/swagger/SwaggerLoader.java | 30 ++++++++++-- 4 files changed, 102 insertions(+), 4 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 9b7b563202d..44cc66e257c 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; @@ -133,4 +134,11 @@ public void onCreateMicroserviceVersion(CreateMicroserviceVersionEvent event) { public void destroy() { scbEngine.getEventBus().unregister(this); } + + @EnableExceptionPropagation + @SubscriberOrder(-800) + @Subscribe + 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 ad1be38e707..2ad3b69b880 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; @@ -37,6 +39,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,9 +184,7 @@ private Swagger loadFromResource(String path) { private Swagger loadFromRemote(Microservice microservice, Collection instances, String schemaId) { - // The client does not restart, the serviceId changes after the provider is upgraded. As a result, - // the same schema is loaded repeatedly. - 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) { @@ -199,7 +200,8 @@ private Swagger loadFromRemote(Microservice microservice, Collection serviceIds = event.getServiceIds(); + if (CollectionUtils.isEmpty(serviceIds)) { + return; + } + List matchKey = remoteSwagger.keySet().stream().filter(key -> { + for (String serviceId : serviceIds) { + if (key.startsWith(serviceId)) { + return true; + } + } + return false; + }).collect(Collectors.toList()); + for (String key : matchKey) { + remoteSwagger.remove(key); + LOGGER.info("remove local appid=[{}], serviceName=[{}], swagger [{}]", event.getAppId(), + event.getServiceName(), key); + } + } } From 602fae9ae7d993e365f07473a75785a11ac599a0 Mon Sep 17 00:00:00 2001 From: chengyouling Date: Fri, 30 Jan 2026 09:41:33 +0800 Subject: [PATCH 4/8] 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 2ad3b69b880..8f9d2d2ed87 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 @@ -200,8 +200,6 @@ private Swagger loadFromRemote(Microservice microservice, Collection Date: Fri, 30 Jan 2026 10:39:42 +0800 Subject: [PATCH 5/8] add note --- .../servicecomb/core/definition/ServiceRegistryListener.java | 1 + 1 file changed, 1 insertion(+) 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 44cc66e257c..7a08325a719 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 @@ -139,6 +139,7 @@ public void destroy() { @SubscriberOrder(-800) @Subscribe public void onRefreshRemoteSwaggerEvent(RefreshRemoteSwaggerEvent event) { + // clear history remote swagger cache when instances is changed. scbEngine.getSwaggerLoader().removeRemoteSwagger(event); } } From 13a1e31aa52eb609206756d5d179c8ae0acd3fef Mon Sep 17 00:00:00 2001 From: chengyouling Date: Fri, 30 Jan 2026 15:41:04 +0800 Subject: [PATCH 6/8] for test --- .../org/apache/servicecomb/foundation/ssl/SSLManager.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLManager.java b/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLManager.java index a0dbafbe035..73b0ade89de 100644 --- a/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLManager.java +++ b/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLManager.java @@ -35,12 +35,16 @@ import javax.net.ssl.X509ExtendedTrustManager; import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * 根据传递的SSLOption构造SSL上下文。请参考JSSE获取相关API的层次参考。 * */ public final class SSLManager { + private static final Logger LOGGER = LoggerFactory.getLogger(SSLManager.class); + private SSLManager() { } @@ -199,7 +203,9 @@ private static String[] getEnabledCiphers(String[] supported, String[] result = new String[enabled.length]; int count = 0; for (String e : enabled) { + LOGGER.info("enabled==================>" + e); for (String s : supported) { + LOGGER.info("supported==================>" + s); if (e.equals(s)) { result[count++] = e; break; From 9b14db617ea763e572d58e1a069c9d7cd454a891 Mon Sep 17 00:00:00 2001 From: chengyouling Date: Fri, 30 Jan 2026 15:58:19 +0800 Subject: [PATCH 7/8] test set jdk17.0.2 --- .github/workflows/unit-test-jdk17.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-test-jdk17.yml b/.github/workflows/unit-test-jdk17.yml index 20102a3aa58..759f307a2ce 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 From bae1af419fa9d790c3134c39367508ab14c9c1f2 Mon Sep 17 00:00:00 2001 From: chengyouling Date: Fri, 30 Jan 2026 16:00:28 +0800 Subject: [PATCH 8/8] delete test log --- .../java/org/apache/servicecomb/foundation/ssl/SSLManager.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLManager.java b/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLManager.java index 73b0ade89de..76f75574a66 100644 --- a/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLManager.java +++ b/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLManager.java @@ -203,9 +203,7 @@ private static String[] getEnabledCiphers(String[] supported, String[] result = new String[enabled.length]; int count = 0; for (String e : enabled) { - LOGGER.info("enabled==================>" + e); for (String s : supported) { - LOGGER.info("supported==================>" + s); if (e.equals(s)) { result[count++] = e; break;