diff --git a/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/component/txtresolver/PropertyResolverTest.java b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/component/txtresolver/PropertyResolverTest.java
index 4c8664f7b47..ed18a70c448 100644
--- a/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/component/txtresolver/PropertyResolverTest.java
+++ b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/component/txtresolver/PropertyResolverTest.java
@@ -91,9 +91,9 @@ public void testDeleteItem() {
@Test
public void testDeleteCommentItem() {
ItemChangeSets changeSets = resolver.resolve(1, "a=b\n\nb=c", mockBaseItemWith2Key1Comment1Blank());
- Assert.assertEquals(2, changeSets.getDeleteItems().size());
- Assert.assertEquals(2, changeSets.getUpdateItems().size());
- Assert.assertEquals(1, changeSets.getCreateItems().size());
+ Assert.assertEquals(1, changeSets.getDeleteItems().size());
+ Assert.assertEquals(3, changeSets.getUpdateItems().size());
+ Assert.assertEquals(0, changeSets.getCreateItems().size());
}
@Test
@@ -120,17 +120,17 @@ public void testUpdateCommentItem() {
+ "a=b\n"
+"\n"
+ "b=c", mockBaseItemWith2Key1Comment1Blank());
- Assert.assertEquals(1, changeSets.getDeleteItems().size());
- Assert.assertEquals(0, changeSets.getUpdateItems().size());
- Assert.assertEquals(1, changeSets.getCreateItems().size());
+ Assert.assertEquals(0, changeSets.getDeleteItems().size());
+ Assert.assertEquals(1, changeSets.getUpdateItems().size());
+ Assert.assertEquals(0, changeSets.getCreateItems().size());
}
@Test
public void testAllSituation(){
ItemChangeSets changeSets = resolver.resolve(1, "#ww\nd=e\nb=c\na=b\n\nq=w\n#eee", mockBaseItemWith2Key1Comment1Blank());
- Assert.assertEquals(2, changeSets.getDeleteItems().size());
- Assert.assertEquals(2, changeSets.getUpdateItems().size());
- Assert.assertEquals(5, changeSets.getCreateItems().size());
+ Assert.assertEquals(0, changeSets.getDeleteItems().size());
+ Assert.assertEquals(4, changeSets.getUpdateItems().size());
+ Assert.assertEquals(3, changeSets.getCreateItems().size());
}
/**
diff --git a/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/controller/GlobalSearchControllerTest.java b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/controller/GlobalSearchControllerTest.java
new file mode 100644
index 00000000000..03231dcc59e
--- /dev/null
+++ b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/controller/GlobalSearchControllerTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2024 Apollo Authors
+ *
+ * Licensed 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 com.ctrip.framework.apollo.portal.controller;
+
+/**
+ * @author hujiyuan 2024-08-10
+ */
+
+import com.ctrip.framework.apollo.common.http.SearchResponseEntity;
+import com.ctrip.framework.apollo.portal.component.config.PortalConfig;
+import com.ctrip.framework.apollo.portal.entity.vo.ItemInfo;
+import com.ctrip.framework.apollo.portal.service.GlobalSearchService;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.util.*;
+
+import static org.mockito.Mockito.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(MockitoJUnitRunner.class)
+public class GlobalSearchControllerTest {
+
+ private MockMvc mockMvc;
+
+ @Mock
+ private PortalConfig portalConfig;
+
+ @Mock
+ private GlobalSearchService globalSearchService;
+
+ @InjectMocks
+ private GlobalSearchController globalSearchController;
+
+ private final int perEnvSearchMaxResults = 200;
+
+ @Before
+ public void setUp() {
+ when(portalConfig.getPerEnvSearchMaxResults()).thenReturn(perEnvSearchMaxResults);
+ mockMvc = MockMvcBuilders.standaloneSetup(globalSearchController).build();
+ }
+
+ @Test
+ public void testGet_ItemInfo_BySearch_WithKeyAndValueAndActiveEnvs_ReturnEmptyItemInfos() throws Exception {
+ when(globalSearchService.getAllEnvItemInfoBySearch(anyString(), anyString(),eq(0),eq(perEnvSearchMaxResults))).thenReturn(SearchResponseEntity.ok(new ArrayList<>()));
+ mockMvc.perform(MockMvcRequestBuilders.get("/global-search/item-info/by-key-or-value")
+ .contentType(MediaType.APPLICATION_JSON)
+ .param("key", "query-key")
+ .param("value", "query-value"))
+ .andExpect(status().isOk())
+ .andExpect(content().json("{\"body\":[],\"hasMoreData\":false,\"message\":\"OK\",\"code\":200}"));
+ verify(portalConfig,times(1)).getPerEnvSearchMaxResults();
+ verify(globalSearchService,times(1)).getAllEnvItemInfoBySearch(anyString(), anyString(),eq(0),eq(perEnvSearchMaxResults));
+ }
+
+ @Test
+ public void testGet_ItemInfo_BySearch_WithKeyAndValueAndActiveEnvs_ReturnExpectedItemInfos_ButOverPerEnvLimit() throws Exception {
+ List allEnvMockItemInfos = new ArrayList<>();
+ allEnvMockItemInfos.add(new ItemInfo("appid1","env1","cluster1","namespace1","query-key","query-value"));
+ allEnvMockItemInfos.add(new ItemInfo("appid2","env2","cluster2","namespace2","query-key","query-value"));
+ when(globalSearchService.getAllEnvItemInfoBySearch(eq("query-key"), eq("query-value"),eq(0),eq(perEnvSearchMaxResults))).thenReturn(SearchResponseEntity.okWithMessage(allEnvMockItemInfos,"In DEV , PRO , more than "+perEnvSearchMaxResults+" items found (Exceeded the maximum search quantity for a single environment). Please enter more precise criteria to narrow down the search scope."));
+ mockMvc.perform(MockMvcRequestBuilders.get("/global-search/item-info/by-key-or-value")
+ .contentType(MediaType.APPLICATION_JSON)
+ .param("key", "query-key")
+ .param("value", "query-value"))
+ .andExpect(status().isOk())
+ .andExpect(content().json("{\"body\":[" +
+ " { \"appId\": \"appid1\",\n" +
+ " \"envName\": \"env1\",\n" +
+ " \"clusterName\": \"cluster1\",\n" +
+ " \"namespaceName\": \"namespace1\",\n" +
+ " \"key\": \"query-key\",\n" +
+ " \"value\": \"query-value\"}," +
+ " { \"appId\": \"appid2\",\n" +
+ " \"envName\": \"env2\",\n" +
+ " \"clusterName\": \"cluster2\",\n" +
+ " \"namespaceName\": \"namespace2\",\n" +
+ " \"key\": \"query-key\",\n" +
+ " \"value\": \"query-value\"}],\"hasMoreData\":true,\"message\":\"In DEV , PRO , more than 200 items found (Exceeded the maximum search quantity for a single environment). Please enter more precise criteria to narrow down the search scope.\",\"code\":200}"));
+ verify(portalConfig,times(1)).getPerEnvSearchMaxResults();
+ verify(globalSearchService, times(1)).getAllEnvItemInfoBySearch(eq("query-key"), eq("query-value"),eq(0),eq(perEnvSearchMaxResults));
+ }
+
+ @Test
+ public void testGet_ItemInfo_BySearch_WithKeyAndValueAndActiveEnvs_ReturnExpectedItemInfos() throws Exception {
+ List allEnvMockItemInfos = new ArrayList<>();
+ allEnvMockItemInfos.add(new ItemInfo("appid1","env1","cluster1","namespace1","query-key","query-value"));
+ allEnvMockItemInfos.add(new ItemInfo("appid2","env2","cluster2","namespace2","query-key","query-value"));
+ when(globalSearchService.getAllEnvItemInfoBySearch(eq("query-key"), eq("query-value"),eq(0),eq(perEnvSearchMaxResults))).thenReturn(SearchResponseEntity.ok(allEnvMockItemInfos));
+
+ mockMvc.perform(MockMvcRequestBuilders.get("/global-search/item-info/by-key-or-value")
+ .contentType(MediaType.APPLICATION_JSON)
+ .param("key", "query-key")
+ .param("value", "query-value"))
+ .andExpect(status().isOk())
+ .andExpect(content().json("{\"body\":[" +
+ " { \"appId\": \"appid1\",\n" +
+ " \"envName\": \"env1\",\n" +
+ " \"clusterName\": \"cluster1\",\n" +
+ " \"namespaceName\": \"namespace1\",\n" +
+ " \"key\": \"query-key\",\n" +
+ " \"value\": \"query-value\"}," +
+ " { \"appId\": \"appid2\",\n" +
+ " \"envName\": \"env2\",\n" +
+ " \"clusterName\": \"cluster2\",\n" +
+ " \"namespaceName\": \"namespace2\",\n" +
+ " \"key\": \"query-key\",\n" +
+ " \"value\": \"query-value\"}],\"hasMoreData\":false,\"message\":\"OK\",\"code\":200}"));
+ verify(globalSearchService, times(1)).getAllEnvItemInfoBySearch(eq("query-key"), eq("query-value"),eq(0),eq(perEnvSearchMaxResults));
+ }
+
+}
diff --git a/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/GlobalSearchServiceTest.java b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/GlobalSearchServiceTest.java
new file mode 100644
index 00000000000..661a692447d
--- /dev/null
+++ b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/GlobalSearchServiceTest.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2024 Apollo Authors
+ *
+ * Licensed 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 com.ctrip.framework.apollo.portal.service;
+
+/**
+ * @author hujiyuan 2024-08-10
+ */
+
+import com.ctrip.framework.apollo.common.dto.ItemInfoDTO;
+import com.ctrip.framework.apollo.common.dto.PageDTO;
+import com.ctrip.framework.apollo.common.http.SearchResponseEntity;
+import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
+import com.ctrip.framework.apollo.portal.component.PortalSettings;
+import com.ctrip.framework.apollo.portal.entity.vo.ItemInfo;
+import com.ctrip.framework.apollo.portal.environment.Env;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.springframework.data.domain.PageRequest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class GlobalSearchServiceTest {
+
+ @Mock
+ private AdminServiceAPI.ItemAPI itemAPI;
+
+ @Mock
+ private PortalSettings portalSettings;
+
+ @InjectMocks
+ private GlobalSearchService globalSearchService;
+
+ private final List activeEnvs = new ArrayList<>();
+
+ @Before
+ public void setUp() {
+ when(portalSettings.getActiveEnvs()).thenReturn(activeEnvs);
+ }
+
+ @Test
+ public void testGet_PerEnv_ItemInfo_BySearch_withKeyAndValue_ReturnExpectedItemInfos() {
+ activeEnvs.add(Env.DEV);
+ activeEnvs.add(Env.PRO);
+
+ ItemInfoDTO itemInfoDTO = new ItemInfoDTO("TestApp","TestCluster","TestNamespace","TestKey","TestValue");
+ List mockItemInfoDTOs = new ArrayList<>();
+ mockItemInfoDTOs.add(itemInfoDTO);
+ Mockito.when(itemAPI.getPerEnvItemInfoBySearch(any(Env.class), eq("TestKey"), eq("TestValue"), eq(0), eq(1))).thenReturn(new PageDTO<>(mockItemInfoDTOs, PageRequest.of(0, 1), 1L));
+ SearchResponseEntity> mockItemInfos = globalSearchService.getAllEnvItemInfoBySearch("TestKey", "TestValue", 0, 1);
+ assertEquals(2, mockItemInfos.getBody().size());
+
+ List devMockItemInfos = new ArrayList<>();
+ List proMockItemInfos = new ArrayList<>();
+ List allEnvMockItemInfos = new ArrayList<>();
+ devMockItemInfos.add(new ItemInfo("TestApp", Env.DEV.getName(), "TestCluster", "TestNamespace", "TestKey", "TestValue"));
+ proMockItemInfos.add(new ItemInfo("TestApp", Env.PRO.getName(), "TestCluster", "TestNamespace", "TestKey", "TestValue"));
+ allEnvMockItemInfos.addAll(devMockItemInfos);
+ allEnvMockItemInfos.addAll(proMockItemInfos);
+
+ verify(itemAPI,times(2)).getPerEnvItemInfoBySearch(any(Env.class), eq("TestKey"), eq("TestValue"), eq(0), eq(1));
+ verify(portalSettings,times(1)).getActiveEnvs();
+ assertEquals(allEnvMockItemInfos.toString(), mockItemInfos.getBody().toString());
+ }
+
+ @Test
+ public void testGet_PerEnv_ItemInfo_withKeyAndValue_BySearch_ReturnEmptyItemInfos() {
+ activeEnvs.add(Env.DEV);
+ activeEnvs.add(Env.PRO);
+ Mockito.when(itemAPI.getPerEnvItemInfoBySearch(any(Env.class), anyString(), anyString(), eq(0), eq(1)))
+ .thenReturn(new PageDTO<>(new ArrayList<>(), PageRequest.of(0, 1), 0L));
+ SearchResponseEntity> result = globalSearchService.getAllEnvItemInfoBySearch("NonExistentKey", "NonExistentValue", 0, 1);
+ assertEquals(0, result.getBody().size());
+ }
+
+ @Test
+ public void testGet_PerEnv_ItemInfo_BySearch_withKeyAndValue_ReturnExpectedItemInfos_ButOverPerEnvLimit() {
+ activeEnvs.add(Env.DEV);
+ activeEnvs.add(Env.PRO);
+
+ ItemInfoDTO itemInfoDTO = new ItemInfoDTO("TestApp","TestCluster","TestNamespace","TestKey","TestValue");
+ List mockItemInfoDTOs = new ArrayList<>();
+ mockItemInfoDTOs.add(itemInfoDTO);
+ Mockito.when(itemAPI.getPerEnvItemInfoBySearch(any(Env.class), eq("TestKey"), eq("TestValue"), eq(0), eq(1))).thenReturn(new PageDTO<>(mockItemInfoDTOs, PageRequest.of(0, 1), 2L));
+ SearchResponseEntity> mockItemInfos = globalSearchService.getAllEnvItemInfoBySearch("TestKey", "TestValue", 0, 1);
+ assertEquals(2, mockItemInfos.getBody().size());
+
+ List devMockItemInfos = new ArrayList<>();
+ List proMockItemInfos = new ArrayList<>();
+ List allEnvMockItemInfos = new ArrayList<>();
+ devMockItemInfos.add(new ItemInfo("TestApp", Env.DEV.getName(), "TestCluster", "TestNamespace", "TestKey", "TestValue"));
+ proMockItemInfos.add(new ItemInfo("TestApp", Env.PRO.getName(), "TestCluster", "TestNamespace", "TestKey", "TestValue"));
+ allEnvMockItemInfos.addAll(devMockItemInfos);
+ allEnvMockItemInfos.addAll(proMockItemInfos);
+ String message = "In DEV , PRO , more than 1 items found (Exceeded the maximum search quantity for a single environment). Please enter more precise criteria to narrow down the search scope.";
+ verify(itemAPI,times(2)).getPerEnvItemInfoBySearch(any(Env.class), eq("TestKey"), eq("TestValue"), eq(0), eq(1));
+ verify(portalSettings,times(1)).getActiveEnvs();
+ assertEquals(allEnvMockItemInfos.toString(), mockItemInfos.getBody().toString());
+ assertEquals(message, mockItemInfos.getMessage());
+ }
+
+}
diff --git a/changes/changes-2.4.0.md b/changes/changes-2.4.0.md
new file mode 100644
index 00000000000..3ebe2e98381
--- /dev/null
+++ b/changes/changes-2.4.0.md
@@ -0,0 +1,14 @@
+Changes by Version
+==================
+Release Notes.
+
+Apollo 2.4.0
+
+------------------
+* [Update the server config link in system info page](https://github.com/apolloconfig/apollo/pull/5204)
+* [Feature support portal restTemplate Client connection pool config](https://github.com/apolloconfig/apollo/pull/5200)
+* [Feature added the ability for administrators to globally search for Value](https://github.com/apolloconfig/apollo/pull/5182)
+* [Feature support the observe status access-key for pre-check and logging only](https://github.com/apolloconfig/apollo/pull/5236)
+
+------------------
+All issues and pull requests are [here](https://github.com/apolloconfig/apollo/milestone/15?closed=1)
diff --git a/doc/images/namespace-num-limit-enabled.png b/doc/images/namespace-num-limit-enabled.png
new file mode 100644
index 00000000000..a415132aa12
Binary files /dev/null and b/doc/images/namespace-num-limit-enabled.png differ
diff --git a/doc/images/namespace-num-limit-white.png b/doc/images/namespace-num-limit-white.png
new file mode 100644
index 00000000000..34bb884ca90
Binary files /dev/null and b/doc/images/namespace-num-limit-white.png differ
diff --git a/doc/images/namespace-num-limit.png b/doc/images/namespace-num-limit.png
new file mode 100644
index 00000000000..45f22e79956
Binary files /dev/null and b/doc/images/namespace-num-limit.png differ
diff --git a/docs/en/README.md b/docs/en/README.md
index 46fb251756f..d76c4540aa2 100644
--- a/docs/en/README.md
+++ b/docs/en/README.md
@@ -37,6 +37,10 @@ Demo Environment:
* **Grayscale release**
* Support grayscale configuration release, for example, after clicking release, it will only take effect for some application instances. After a period of observation, we could push the configurations to all application instances if there is no problem
+- **Global Search Configuration Items**
+ - A fuzzy search of the key and value of a configuration item finds in which application, environment, cluster, namespace the configuration item with the corresponding value is used
+ - It is easy for administrators and SRE roles to quickly and easily find and change the configuration values of resources by highlighting, paging and jumping through configurations
+
* **Authorization management, release approval and operation audit**
* Great authorization mechanism is designed for applications and configurations management, and the management of configurations is divided into two operations: editing and publishing, therefore greatly reducing human errors
* All operations have audit logs for easy tracking of problems
diff --git a/docs/en/client/java-sdk-user-guide.md b/docs/en/client/java-sdk-user-guide.md
index fb65ba35241..3b61cb62bf3 100644
--- a/docs/en/client/java-sdk-user-guide.md
+++ b/docs/en/client/java-sdk-user-guide.md
@@ -423,8 +423,6 @@ Starting from version 2.4.0, the observability of the client has been enhanced.
`apollo.client.monitor.jmx.enabled`: Exposes Monitor data in JMX format. If enabled, tools like J-console and Jprofiler can be used to view the relevant information. The default is false.
-![Monitor Configuration](https://cdn.jsdelivr.net/gh/Rawven/image@main/2024-08-24-14-59-01-image.png)
-
`apollo.client.monitor.exception-queue-size`: Sets the maximum number of exceptions that the Monitor can store. The default value is 25.
`apollo.client.monitor.external.type`: **Non-standard configuration item**, used to activate the corresponding monitoring system's Exporter when exporting metric data. For example, if the apollo-plugin-client-prometheus is introduced, "prometheus" can be specified to enable it. The values available for configuration depend on the MetricsExporter SPI introduced (official or custom implementations). This design allows for easy extensibility. If multiple, incorrect, or no values are set, no Exporter will be enabled.
@@ -570,7 +568,7 @@ apollo:
After starting the application, you can view it using J-console or J-profiler; here, we use J-profiler as an example.
-![](https://raw.githubusercontent.com/Rawven/image/main/20240828003803.png)
+![](https://raw.githubusercontent.com/Rawven/image/main/20241020224657.png)
#### 3.1.5.2 Exporting Metrics via Prometheus
@@ -612,18 +610,31 @@ public class TestController {
After starting the application, let Prometheus listen to this interface, and you will see request logs with a similar format.
```
+# TYPE apollo_client_thread_pool_active_task_count gauge
+# HELP apollo_client_thread_pool_active_task_count apollo gauge metrics
+apollo_client_thread_pool_active_task_count{thread_pool_name="RemoteConfigRepository"} 0.0
+apollo_client_thread_pool_active_task_count{thread_pool_name="AbstractApolloClientMetricsExporter"} 1.0
+apollo_client_thread_pool_active_task_count{thread_pool_name="AbstractConfigFile"} 0.0
+apollo_client_thread_pool_active_task_count{thread_pool_name="AbstractConfig"} 0.0
+# TYPE apollo_client_namespace_timeout gauge
+# HELP apollo_client_namespace_timeout apollo gauge metrics
+apollo_client_namespace_timeout 0.0
+# TYPE apollo_client_thread_pool_pool_size gauge
+# HELP apollo_client_thread_pool_pool_size apollo gauge metrics
+apollo_client_thread_pool_pool_size{thread_pool_name="RemoteConfigRepository"} 1.0
+apollo_client_thread_pool_pool_size{thread_pool_name="AbstractApolloClientMetricsExporter"} 1.0
+apollo_client_thread_pool_pool_size{thread_pool_name="AbstractConfigFile"} 0.0
+apollo_client_thread_pool_pool_size{thread_pool_name="AbstractConfig"} 0.0
# TYPE apollo_client_thread_pool_queue_remaining_capacity gauge
# HELP apollo_client_thread_pool_queue_remaining_capacity apollo gauge metrics
apollo_client_thread_pool_queue_remaining_capacity{thread_pool_name="RemoteConfigRepository"} 2.147483647E9
apollo_client_thread_pool_queue_remaining_capacity{thread_pool_name="AbstractApolloClientMetricsExporter"} 2.147483647E9
apollo_client_thread_pool_queue_remaining_capacity{thread_pool_name="AbstractConfigFile"} 0.0
apollo_client_thread_pool_queue_remaining_capacity{thread_pool_name="AbstractConfig"} 0.0
-# TYPE apollo_client_thread_pool_core_pool_size gauge
-# HELP apollo_client_thread_pool_core_pool_size apollo gauge metrics
-apollo_client_thread_pool_core_pool_size{thread_pool_name="RemoteConfigRepository"} 1.0
-apollo_client_thread_pool_core_pool_size{thread_pool_name="AbstractApolloClientMetricsExporter"} 1.0
-apollo_client_thread_pool_core_pool_size{thread_pool_name="AbstractConfigFile"} 0.0
-apollo_client_thread_pool_core_pool_size{thread_pool_name="AbstractConfig"} 0.0
+# TYPE apollo_client_exception_num counter
+# HELP apollo_client_exception_num apollo counter metrics
+apollo_client_exception_num_total 1404.0
+apollo_client_exception_num_created 1.729435502796E9
# TYPE apollo_client_thread_pool_largest_pool_size gauge
# HELP apollo_client_thread_pool_largest_pool_size apollo gauge metrics
apollo_client_thread_pool_largest_pool_size{thread_pool_name="RemoteConfigRepository"} 1.0
@@ -632,60 +643,47 @@ apollo_client_thread_pool_largest_pool_size{thread_pool_name="AbstractConfigFile
apollo_client_thread_pool_largest_pool_size{thread_pool_name="AbstractConfig"} 0.0
# TYPE apollo_client_thread_pool_queue_size gauge
# HELP apollo_client_thread_pool_queue_size apollo gauge metrics
-apollo_client_thread_pool_queue_size{thread_pool_name="RemoteConfigRepository"} 2.0
+apollo_client_thread_pool_queue_size{thread_pool_name="RemoteConfigRepository"} 352.0
apollo_client_thread_pool_queue_size{thread_pool_name="AbstractApolloClientMetricsExporter"} 0.0
apollo_client_thread_pool_queue_size{thread_pool_name="AbstractConfigFile"} 0.0
apollo_client_thread_pool_queue_size{thread_pool_name="AbstractConfig"} 0.0
-# TYPE apollo_client_thread_pool_pool_size gauge
-# HELP apollo_client_thread_pool_pool_size apollo gauge metrics
-apollo_client_thread_pool_pool_size{thread_pool_name="RemoteConfigRepository"} 1.0
-apollo_client_thread_pool_pool_size{thread_pool_name="AbstractApolloClientMetricsExporter"} 1.0
-apollo_client_thread_pool_pool_size{thread_pool_name="AbstractConfigFile"} 0.0
-apollo_client_thread_pool_pool_size{thread_pool_name="AbstractConfig"} 0.0
-# TYPE apollo_client_namespace_item_num gauge
-# HELP apollo_client_namespace_item_num apollo gauge metrics
-apollo_client_namespace_item_num{namespace="application"} 8.0
-apollo_client_namespace_item_num{namespace="application1"} 2.0
-# TYPE apollo_client_thread_pool_completed_task_count gauge
-# HELP apollo_client_thread_pool_completed_task_count apollo gauge metrics
-apollo_client_thread_pool_completed_task_count{thread_pool_name="RemoteConfigRepository"} 2.0
-apollo_client_thread_pool_completed_task_count{thread_pool_name="AbstractApolloClientMetricsExporter"} 0.0
-apollo_client_thread_pool_completed_task_count{thread_pool_name="AbstractConfigFile"} 0.0
-apollo_client_thread_pool_completed_task_count{thread_pool_name="AbstractConfig"} 0.0
+# TYPE apollo_client_namespace_usage counter
+# HELP apollo_client_namespace_usage apollo counter metrics
+apollo_client_namespace_usage_total{namespace="application"} 11.0
+apollo_client_namespace_usage_created{namespace="application"} 1.729435502791E9
+# TYPE apollo_client_thread_pool_core_pool_size gauge
+# HELP apollo_client_thread_pool_core_pool_size apollo gauge metrics
+apollo_client_thread_pool_core_pool_size{thread_pool_name="RemoteConfigRepository"} 1.0
+apollo_client_thread_pool_core_pool_size{thread_pool_name="AbstractApolloClientMetricsExporter"} 1.0
+apollo_client_thread_pool_core_pool_size{thread_pool_name="AbstractConfigFile"} 0.0
+apollo_client_thread_pool_core_pool_size{thread_pool_name="AbstractConfig"} 0.0
# TYPE apollo_client_namespace_not_found gauge
# HELP apollo_client_namespace_not_found apollo gauge metrics
-apollo_client_namespace_not_found 0.0
+apollo_client_namespace_not_found 351.0
# TYPE apollo_client_thread_pool_total_task_count gauge
# HELP apollo_client_thread_pool_total_task_count apollo gauge metrics
-apollo_client_thread_pool_total_task_count{thread_pool_name="RemoteConfigRepository"} 4.0
-apollo_client_thread_pool_total_task_count{thread_pool_name="AbstractApolloClientMetricsExporter"} 1.0
+apollo_client_thread_pool_total_task_count{thread_pool_name="RemoteConfigRepository"} 353.0
+apollo_client_thread_pool_total_task_count{thread_pool_name="AbstractApolloClientMetricsExporter"} 4.0
apollo_client_thread_pool_total_task_count{thread_pool_name="AbstractConfigFile"} 0.0
apollo_client_thread_pool_total_task_count{thread_pool_name="AbstractConfig"} 0.0
-# TYPE apollo_client_namespace_usage counter
-# HELP apollo_client_namespace_usage apollo counter metrics
-apollo_client_namespace_usage_total{namespace="application"} 1.0
-apollo_client_namespace_usage_created{namespace="application"} 1.725899226271E9
-apollo_client_namespace_usage_total{namespace="application1"} 1.0
-apollo_client_namespace_usage_created{namespace="application1"} 1.72589922627E9
+# TYPE apollo_client_namespace_first_load_time_spend_in_ms gauge
+# HELP apollo_client_namespace_first_load_time_spend_in_ms apollo gauge metrics
+apollo_client_namespace_first_load_time_spend_in_ms{namespace="application"} 108.0
# TYPE apollo_client_thread_pool_maximum_pool_size gauge
# HELP apollo_client_thread_pool_maximum_pool_size apollo gauge metrics
apollo_client_thread_pool_maximum_pool_size{thread_pool_name="RemoteConfigRepository"} 2.147483647E9
apollo_client_thread_pool_maximum_pool_size{thread_pool_name="AbstractApolloClientMetricsExporter"} 2.147483647E9
apollo_client_thread_pool_maximum_pool_size{thread_pool_name="AbstractConfigFile"} 2.147483647E9
apollo_client_thread_pool_maximum_pool_size{thread_pool_name="AbstractConfig"} 2.147483647E9
-# TYPE apollo_client_namespace_first_load_time_spend_in_ms gauge
-# HELP apollo_client_namespace_first_load_time_spend_in_ms apollo gauge metrics
-apollo_client_namespace_first_load_time_spend_in_ms{namespace="application"} 99.0
-apollo_client_namespace_first_load_time_spend_in_ms{namespace="application1"} 40.0
-# TYPE apollo_client_thread_pool_active_task_count gauge
-# HELP apollo_client_thread_pool_active_task_count apollo gauge metrics
-apollo_client_thread_pool_active_task_count{thread_pool_name="RemoteConfigRepository"} 0.0
-apollo_client_thread_pool_active_task_count{thread_pool_name="AbstractApolloClientMetricsExporter"} 1.0
-apollo_client_thread_pool_active_task_count{thread_pool_name="AbstractConfigFile"} 0.0
-apollo_client_thread_pool_active_task_count{thread_pool_name="AbstractConfig"} 0.0
-# TYPE apollo_client_namespace_timeout gauge
-# HELP apollo_client_namespace_timeout apollo gauge metrics
-apollo_client_namespace_timeout 0.0
+# TYPE apollo_client_namespace_item_num gauge
+# HELP apollo_client_namespace_item_num apollo gauge metrics
+apollo_client_namespace_item_num{namespace="application"} 9.0
+# TYPE apollo_client_thread_pool_completed_task_count gauge
+# HELP apollo_client_thread_pool_completed_task_count apollo gauge metrics
+apollo_client_thread_pool_completed_task_count{thread_pool_name="RemoteConfigRepository"} 1.0
+apollo_client_thread_pool_completed_task_count{thread_pool_name="AbstractApolloClientMetricsExporter"} 3.0
+apollo_client_thread_pool_completed_task_count{thread_pool_name="AbstractConfigFile"} 0.0
+apollo_client_thread_pool_completed_task_count{thread_pool_name="AbstractConfig"} 0.0
# EOF
```
diff --git a/docs/en/deployment/distributed-deployment-guide.md b/docs/en/deployment/distributed-deployment-guide.md
index 3251d4c5d5e..4dbe8dd7586 100644
--- a/docs/en/deployment/distributed-deployment-guide.md
+++ b/docs/en/deployment/distributed-deployment-guide.md
@@ -769,9 +769,9 @@ apollo.service.registry.cluster=same name with apollo Cluster
```
2. (optional) If you want to customize Config Service and Admin Service's uri for Client,
-for example when deploying on the intranet,
-if you don't want to expose the intranet ip,
-you can add a property in `config/application-github.properties` of the Config Service and Admin Service installation package
+ for example when deploying on the intranet,
+ if you don't want to expose the intranet ip,
+ you can add a property in `config/application-github.properties` of the Config Service and Admin Service installation package
```properties
apollo.service.registry.uri=http://your-ip-or-domain:${server.port}/
```
@@ -1447,6 +1447,14 @@ The default is true, which makes it easy to quickly search for configurations by
If set to false, this feature is disabled
+### 3.1.14 apollo.portal.search.perEnvMaxResults - set the Administrator Tool-Global Search for Value function's maximum number of search results for a single individual environment
+
+> For versions 2.4.0 and above
+
+Default is 200, which means that each environment will return up to 200 results in a single search operation.
+
+Modifying this parameter may affect the performance of the search function, so before modifying it, you should conduct sufficient testing and adjust the value of `apollo.portal.search.perEnvMaxResults` appropriately according to the actual business requirements and system resources to balance the performance and the number of search results.
+
## 3.2 Adjusting ApolloConfigDB configuration
Configuration items are uniformly stored in the ApolloConfigDB.ServerConfig table. It should be noted that each environment's ApolloConfigDB.ServerConfig needs to be configured separately, and the modification takes effect in real time for one minute afterwards.
diff --git a/docs/en/design/apollo-design.md b/docs/en/design/apollo-design.md
index f078c1881d2..0061f696f20 100644
--- a/docs/en/design/apollo-design.md
+++ b/docs/en/design/apollo-design.md
@@ -130,7 +130,7 @@ Why do we use Eureka as a service registry instead of the traditional zk and etc
### 1.3.2 Admin Service
* Provide configuration management interface
-* Provides interfaces for configuration modification, publishing, etc.
+* Provides interfaces for configuration modification, publishing, retrieval, etc.
* Interface service object is Portal
### 1.3.3 Meta Server
diff --git a/docs/en/design/apollo-introduction.md b/docs/en/design/apollo-introduction.md
index a001f5a3a81..f846e6be867 100644
--- a/docs/en/design/apollo-introduction.md
+++ b/docs/en/design/apollo-introduction.md
@@ -78,7 +78,13 @@ It is precisely based on the particularity of configuration that Apollo has been
* **Client configuration information monitoring**
* You can easily see which instances the configuration is being used on the interface
+**Global Search Configuration Items**
+
+- A fuzzy search of the key and value of a configuration item finds in which application, environment, cluster, namespace the configuration item with the corresponding value is used
+- It is easy for administrators and SRE roles to quickly and easily find and change the configuration values of resources by highlighting, paging and jumping through configurations
+
**Java and .Net native clients available**
+
* Provides native clients of Java and .Net for easy application integration
* Support Spring Placeholder, Annotation and Spring Boot's ConfigurationProperties for easy application use (requires Spring 3.1.1+)
* Also provides Http interface, non-Java and .Net applications can also be easily used
diff --git a/docs/en/images/Configuration query-Non properties.png b/docs/en/images/Configuration query-Non properties.png
new file mode 100644
index 00000000000..1a355074cbc
Binary files /dev/null and b/docs/en/images/Configuration query-Non properties.png differ
diff --git a/docs/en/images/Configuration query-properties.png b/docs/en/images/Configuration query-properties.png
new file mode 100644
index 00000000000..2f8fd771109
Binary files /dev/null and b/docs/en/images/Configuration query-properties.png differ
diff --git a/docs/en/images/System-parameterization-of-global-search-configuration-items.png b/docs/en/images/System-parameterization-of-global-search-configuration-items.png
new file mode 100644
index 00000000000..4f47b58cd7b
Binary files /dev/null and b/docs/en/images/System-parameterization-of-global-search-configuration-items.png differ
diff --git a/docs/en/portal/apollo-user-guide.md b/docs/en/portal/apollo-user-guide.md
index cb84a8e6faa..d084ab5a0aa 100644
--- a/docs/en/portal/apollo-user-guide.md
+++ b/docs/en/portal/apollo-user-guide.md
@@ -133,6 +133,20 @@ The rollback mechanism here is similar to the release system, where the rollback
The rollback in Apollo is a similar mechanism. Clicking rollback rolls back the configuration published to the client to the previous published version, which means that the configuration read by the client will be restored to the previous version, but the configuration in the edited state on the page will not be rolled back, so that the developer can re-publish after fixing the configuration.
+## 1.7 Configuration queries (administrator privileges)
+
+After a configuration has been added or modified, the administrator user can make a query for the configuration item it belongs to as well as jump to modifications by going to the `Administrator Tools - Global Search for Value` page.
+
+The query here is a fuzzy search, where at least one of the key and value of the configuration item is searched to find out in which application, environment, cluster, namespace the configuration is used.
+
+- Properties format configuration can be retrieved directly from the key and value
+
+![Configuration query-properties](../images/Configuration query-properties.png)
+
+- xml, json, yml, yaml, txt and other formats configuration, because the storage of content-value storage, so you can key = content, value = configuration item content, retrieval
+
+![Configuration query-Non properties](../images/Configuration query-Non properties.png)
+
# II. Public component access guide
## 2.1 Difference between public components and common applications
@@ -482,6 +496,42 @@ Apollo has added an access key mechanism since version 1.6.0, so that only authe
3. Client-side [configure access key](en/client/java-sdk-user-guide?id=_1244-configuring-access-keys) .
+## 6.3 System parameterization of global search configuration items
+
+Starting from version 2.4.0, apollo-portal adds the ability to globally search for configuration items by fuzzy retrieval of the key and value of a configuration item to find out which application, environment, cluster, or namespace the configuration item with the corresponding value is used in. In order to prevent memory overflow (OOM) problems when performing global view searches of configuration items, we introduce a system parameter `apollo.portal.search.perEnvMaxResults`, which is used to limit the number of maximum search results per environment configuration item in a single search. By default, this value is set to `200`, but administrators can adjust it to suit their actual needs.
+
+**Setting method:**
+
+1. Log in to the Apollo Configuration Center interface with a super administrator account.
+2. Just go to the `Administrator Tools - System Parameters` page and add or modify the `apollo.portal.search.perEnvMaxResults` configuration item.
+
+Please note that modifications to system parameters may affect the performance of the search function, so you should perform adequate testing and ensure that you understand exactly what the parameters do before making changes.
+
+![System-parameterization-of-global-search-configuration-items](../images/System-parameterization-of-global-search-configuration-items.png)
+
+
+
+## 6.4 Parameter settings for limiting the number of namespaces in the appld+cluster dimension
+
+Starting from version 2.4.0, apollo-portal provides the function of checking the upper limit of the number of namespaces that can be created under the appld+cluster dimension. This function is disabled by default and needs to be enabled by configuring the system `namespace.num.limit.enabled`. At the same time, the system parameter `namespace.num.limit` is provided to dynamically configure the upper limit of the number of Namespaces under the appld+cluster dimension. The default value is 200. Considering that some basic components such as gateways, message queues, Redis, and databases require special processing, a new system parameter `namespace.num.limit.white` is added to configure the verification whitelist, which is not affected by the upper limit of the number of Namespaces.
+
+**Setting method:**
+
+1. Log in to the Apollo Configuration Center interface with a super administrator account.
+2. Go to the `Administrator Tools - System Parameters - ConfigDB Configuration Management` page and add or modify the `namespace.num.limit.enabled` configuration item to true/false to enable/disable this function. It is disabled by default.
+
+ ![item-num-limit-enabled](https://cdn.jsdelivr.net/gh/apolloconfig/apollo@master/doc/images/namespace-num-limit-enabled.png)
+
+3. Go to the `Administrator Tools - System Parameters - ConfigDB Configuration Management` page to add or modify the `namespace.num.limit` configuration item to configure the upper limit of the number of namespaces under a single appld+cluster. The default value is 200
+
+ ![item-num-limit](https://cdn.jsdelivr.net/gh/apolloconfig/apollo@master/doc/images/namespace-num-limit.png)
+
+4. Go to `Administrator Tools - System Parameters - ConfigDB Configuration Management` page to add or modify the `namespace.num.limit.white` configuration item to configure the whitelist for namespace quantity limit verification. Multiple AppIds are separated by English commas.
+
+ ![item-num-limit](https://cdn.jsdelivr.net/gh/apolloconfig/apollo@master/doc/images/namespace-num-limit-white.png)
+
+
+
# VII. Best practices
## 7.1 Security Related
diff --git a/docs/zh/README.md b/docs/zh/README.md
index e54c216f0a3..09c04f85647 100644
--- a/docs/zh/README.md
+++ b/docs/zh/README.md
@@ -40,6 +40,10 @@ Java客户端不依赖任何框架,能够运行于所有Java运行时环境,
* **灰度发布**
* 支持配置的灰度发布,比如点了发布后,只对部分应用实例生效,等观察一段时间没问题后再推给所有应用实例。
+- **配置项的全局视角搜索**
+ - 通过对配置项的key与value进行的模糊检索,找到拥有对应值的配置项在哪个应用、环境、集群、命名空间中被使用。
+ - 通过高亮显示、分页与跳转配置等操作,便于让管理员以及SRE角色快速、便捷地找到与更改资源的配置值。
+
* **权限管理、发布审核、操作审计**
* 应用和配置的管理都有完善的权限管理机制,对配置的管理还分为了编辑和发布两个环节,从而减少人为的错误。
* 所有的操作都有审计日志,可以方便的追踪问题。
diff --git a/docs/zh/client/java-sdk-user-guide.md b/docs/zh/client/java-sdk-user-guide.md
index 4abd1b7d612..dd904cf0e32 100644
--- a/docs/zh/client/java-sdk-user-guide.md
+++ b/docs/zh/client/java-sdk-user-guide.md
@@ -408,8 +408,6 @@ apollo.label=YOUR-APOLLO-LABEL
`apollo.client.monitor.jmx.enabled`:是否将Monitor数据以Jmx形式暴露,开启后可以通过J-console,Jprofiler等工具查看相关信息,默认为false
-![](https://cdn.jsdelivr.net/gh/Rawven/image@main/2024-08-24-14-59-01-image.png)
-
`apollo.client.monitor.exception-queue-size`:设置Monitor存储Exception的最大数量,默认值为25
`apollo.client.monitor.external.type`:**非常规配置项**,用于导出指标数据时启用对应监控系统的Exporter,如引入apollo-plugin-client-prometheus则可填写prometheus进行启用,可填配置取决于用户引入的MetricsExporter的SPI使可用官方提供的或自己实现),这种设计是为了用户能更方便的扩展。多填,错填和不填则不启用任何Exporter。
@@ -539,7 +537,7 @@ apollo:
启动应用后,开启J-console或J-profiler即可查看,这里用J-profiler做例子
-![](https://raw.githubusercontent.com/Rawven/image/main/20240828003803.png)
+![](https://raw.githubusercontent.com/Rawven/image/main/20241020224657.png)
#### 3.1.5.2 以Prometheus形式导出指标
引入提供的官方依赖包
@@ -580,18 +578,31 @@ public class TestController {
启动应用后让Prometheus监听该接口,打印请求日志即可发现如下类似格式信息
```
+# TYPE apollo_client_thread_pool_active_task_count gauge
+# HELP apollo_client_thread_pool_active_task_count apollo gauge metrics
+apollo_client_thread_pool_active_task_count{thread_pool_name="RemoteConfigRepository"} 0.0
+apollo_client_thread_pool_active_task_count{thread_pool_name="AbstractApolloClientMetricsExporter"} 1.0
+apollo_client_thread_pool_active_task_count{thread_pool_name="AbstractConfigFile"} 0.0
+apollo_client_thread_pool_active_task_count{thread_pool_name="AbstractConfig"} 0.0
+# TYPE apollo_client_namespace_timeout gauge
+# HELP apollo_client_namespace_timeout apollo gauge metrics
+apollo_client_namespace_timeout 0.0
+# TYPE apollo_client_thread_pool_pool_size gauge
+# HELP apollo_client_thread_pool_pool_size apollo gauge metrics
+apollo_client_thread_pool_pool_size{thread_pool_name="RemoteConfigRepository"} 1.0
+apollo_client_thread_pool_pool_size{thread_pool_name="AbstractApolloClientMetricsExporter"} 1.0
+apollo_client_thread_pool_pool_size{thread_pool_name="AbstractConfigFile"} 0.0
+apollo_client_thread_pool_pool_size{thread_pool_name="AbstractConfig"} 0.0
# TYPE apollo_client_thread_pool_queue_remaining_capacity gauge
# HELP apollo_client_thread_pool_queue_remaining_capacity apollo gauge metrics
apollo_client_thread_pool_queue_remaining_capacity{thread_pool_name="RemoteConfigRepository"} 2.147483647E9
apollo_client_thread_pool_queue_remaining_capacity{thread_pool_name="AbstractApolloClientMetricsExporter"} 2.147483647E9
apollo_client_thread_pool_queue_remaining_capacity{thread_pool_name="AbstractConfigFile"} 0.0
apollo_client_thread_pool_queue_remaining_capacity{thread_pool_name="AbstractConfig"} 0.0
-# TYPE apollo_client_thread_pool_core_pool_size gauge
-# HELP apollo_client_thread_pool_core_pool_size apollo gauge metrics
-apollo_client_thread_pool_core_pool_size{thread_pool_name="RemoteConfigRepository"} 1.0
-apollo_client_thread_pool_core_pool_size{thread_pool_name="AbstractApolloClientMetricsExporter"} 1.0
-apollo_client_thread_pool_core_pool_size{thread_pool_name="AbstractConfigFile"} 0.0
-apollo_client_thread_pool_core_pool_size{thread_pool_name="AbstractConfig"} 0.0
+# TYPE apollo_client_exception_num counter
+# HELP apollo_client_exception_num apollo counter metrics
+apollo_client_exception_num_total 1404.0
+apollo_client_exception_num_created 1.729435502796E9
# TYPE apollo_client_thread_pool_largest_pool_size gauge
# HELP apollo_client_thread_pool_largest_pool_size apollo gauge metrics
apollo_client_thread_pool_largest_pool_size{thread_pool_name="RemoteConfigRepository"} 1.0
@@ -600,60 +611,47 @@ apollo_client_thread_pool_largest_pool_size{thread_pool_name="AbstractConfigFile
apollo_client_thread_pool_largest_pool_size{thread_pool_name="AbstractConfig"} 0.0
# TYPE apollo_client_thread_pool_queue_size gauge
# HELP apollo_client_thread_pool_queue_size apollo gauge metrics
-apollo_client_thread_pool_queue_size{thread_pool_name="RemoteConfigRepository"} 2.0
+apollo_client_thread_pool_queue_size{thread_pool_name="RemoteConfigRepository"} 352.0
apollo_client_thread_pool_queue_size{thread_pool_name="AbstractApolloClientMetricsExporter"} 0.0
apollo_client_thread_pool_queue_size{thread_pool_name="AbstractConfigFile"} 0.0
apollo_client_thread_pool_queue_size{thread_pool_name="AbstractConfig"} 0.0
-# TYPE apollo_client_thread_pool_pool_size gauge
-# HELP apollo_client_thread_pool_pool_size apollo gauge metrics
-apollo_client_thread_pool_pool_size{thread_pool_name="RemoteConfigRepository"} 1.0
-apollo_client_thread_pool_pool_size{thread_pool_name="AbstractApolloClientMetricsExporter"} 1.0
-apollo_client_thread_pool_pool_size{thread_pool_name="AbstractConfigFile"} 0.0
-apollo_client_thread_pool_pool_size{thread_pool_name="AbstractConfig"} 0.0
-# TYPE apollo_client_namespace_item_num gauge
-# HELP apollo_client_namespace_item_num apollo gauge metrics
-apollo_client_namespace_item_num{namespace="application"} 8.0
-apollo_client_namespace_item_num{namespace="application1"} 2.0
-# TYPE apollo_client_thread_pool_completed_task_count gauge
-# HELP apollo_client_thread_pool_completed_task_count apollo gauge metrics
-apollo_client_thread_pool_completed_task_count{thread_pool_name="RemoteConfigRepository"} 2.0
-apollo_client_thread_pool_completed_task_count{thread_pool_name="AbstractApolloClientMetricsExporter"} 0.0
-apollo_client_thread_pool_completed_task_count{thread_pool_name="AbstractConfigFile"} 0.0
-apollo_client_thread_pool_completed_task_count{thread_pool_name="AbstractConfig"} 0.0
+# TYPE apollo_client_namespace_usage counter
+# HELP apollo_client_namespace_usage apollo counter metrics
+apollo_client_namespace_usage_total{namespace="application"} 11.0
+apollo_client_namespace_usage_created{namespace="application"} 1.729435502791E9
+# TYPE apollo_client_thread_pool_core_pool_size gauge
+# HELP apollo_client_thread_pool_core_pool_size apollo gauge metrics
+apollo_client_thread_pool_core_pool_size{thread_pool_name="RemoteConfigRepository"} 1.0
+apollo_client_thread_pool_core_pool_size{thread_pool_name="AbstractApolloClientMetricsExporter"} 1.0
+apollo_client_thread_pool_core_pool_size{thread_pool_name="AbstractConfigFile"} 0.0
+apollo_client_thread_pool_core_pool_size{thread_pool_name="AbstractConfig"} 0.0
# TYPE apollo_client_namespace_not_found gauge
# HELP apollo_client_namespace_not_found apollo gauge metrics
-apollo_client_namespace_not_found 0.0
+apollo_client_namespace_not_found 351.0
# TYPE apollo_client_thread_pool_total_task_count gauge
# HELP apollo_client_thread_pool_total_task_count apollo gauge metrics
-apollo_client_thread_pool_total_task_count{thread_pool_name="RemoteConfigRepository"} 4.0
-apollo_client_thread_pool_total_task_count{thread_pool_name="AbstractApolloClientMetricsExporter"} 1.0
+apollo_client_thread_pool_total_task_count{thread_pool_name="RemoteConfigRepository"} 353.0
+apollo_client_thread_pool_total_task_count{thread_pool_name="AbstractApolloClientMetricsExporter"} 4.0
apollo_client_thread_pool_total_task_count{thread_pool_name="AbstractConfigFile"} 0.0
apollo_client_thread_pool_total_task_count{thread_pool_name="AbstractConfig"} 0.0
-# TYPE apollo_client_namespace_usage counter
-# HELP apollo_client_namespace_usage apollo counter metrics
-apollo_client_namespace_usage_total{namespace="application"} 1.0
-apollo_client_namespace_usage_created{namespace="application"} 1.725899226271E9
-apollo_client_namespace_usage_total{namespace="application1"} 1.0
-apollo_client_namespace_usage_created{namespace="application1"} 1.72589922627E9
+# TYPE apollo_client_namespace_first_load_time_spend_in_ms gauge
+# HELP apollo_client_namespace_first_load_time_spend_in_ms apollo gauge metrics
+apollo_client_namespace_first_load_time_spend_in_ms{namespace="application"} 108.0
# TYPE apollo_client_thread_pool_maximum_pool_size gauge
# HELP apollo_client_thread_pool_maximum_pool_size apollo gauge metrics
apollo_client_thread_pool_maximum_pool_size{thread_pool_name="RemoteConfigRepository"} 2.147483647E9
apollo_client_thread_pool_maximum_pool_size{thread_pool_name="AbstractApolloClientMetricsExporter"} 2.147483647E9
apollo_client_thread_pool_maximum_pool_size{thread_pool_name="AbstractConfigFile"} 2.147483647E9
apollo_client_thread_pool_maximum_pool_size{thread_pool_name="AbstractConfig"} 2.147483647E9
-# TYPE apollo_client_namespace_first_load_time_spend_in_ms gauge
-# HELP apollo_client_namespace_first_load_time_spend_in_ms apollo gauge metrics
-apollo_client_namespace_first_load_time_spend_in_ms{namespace="application"} 99.0
-apollo_client_namespace_first_load_time_spend_in_ms{namespace="application1"} 40.0
-# TYPE apollo_client_thread_pool_active_task_count gauge
-# HELP apollo_client_thread_pool_active_task_count apollo gauge metrics
-apollo_client_thread_pool_active_task_count{thread_pool_name="RemoteConfigRepository"} 0.0
-apollo_client_thread_pool_active_task_count{thread_pool_name="AbstractApolloClientMetricsExporter"} 1.0
-apollo_client_thread_pool_active_task_count{thread_pool_name="AbstractConfigFile"} 0.0
-apollo_client_thread_pool_active_task_count{thread_pool_name="AbstractConfig"} 0.0
-# TYPE apollo_client_namespace_timeout gauge
-# HELP apollo_client_namespace_timeout apollo gauge metrics
-apollo_client_namespace_timeout 0.0
+# TYPE apollo_client_namespace_item_num gauge
+# HELP apollo_client_namespace_item_num apollo gauge metrics
+apollo_client_namespace_item_num{namespace="application"} 9.0
+# TYPE apollo_client_thread_pool_completed_task_count gauge
+# HELP apollo_client_thread_pool_completed_task_count apollo gauge metrics
+apollo_client_thread_pool_completed_task_count{thread_pool_name="RemoteConfigRepository"} 1.0
+apollo_client_thread_pool_completed_task_count{thread_pool_name="AbstractApolloClientMetricsExporter"} 3.0
+apollo_client_thread_pool_completed_task_count{thread_pool_name="AbstractConfigFile"} 0.0
+apollo_client_thread_pool_completed_task_count{thread_pool_name="AbstractConfig"} 0.0
# EOF
```
diff --git a/docs/zh/deployment/distributed-deployment-guide.md b/docs/zh/deployment/distributed-deployment-guide.md
index 4d21e1c80aa..f83d62ac692 100644
--- a/docs/zh/deployment/distributed-deployment-guide.md
+++ b/docs/zh/deployment/distributed-deployment-guide.md
@@ -1392,6 +1392,14 @@ portal上“帮助”链接的地址,默认是Apollo github的wiki首页,可
如果设置为 false,则关闭此功能
+### 3.1.14 apollo.portal.search.perEnvMaxResults - 设置管理员工具-value的全局搜索功能单次单独环境最大搜索结果的数量
+
+> 适用于2.4.0及以上版本
+
+默认为200,意味着每个环境在单次搜索操作中最多返回200条结果
+
+修改该参数可能会影响搜索功能的性能,因此在修改之前应该进行充分的测试,根据实际业务需求和系统资源情况,适当调整`apollo.portal.search.perEnvMaxResults`的值,以平衡性能和搜索结果的数量
+
## 3.2 调整ApolloConfigDB配置
配置项统一存储在ApolloConfigDB.ServerConfig表中,需要注意每个环境的ApolloConfigDB.ServerConfig都需要单独配置,修改完一分钟实时生效。
diff --git a/docs/zh/design/apollo-design.md b/docs/zh/design/apollo-design.md
index e2724800c5f..7cd1b49b2c0 100644
--- a/docs/zh/design/apollo-design.md
+++ b/docs/zh/design/apollo-design.md
@@ -136,7 +136,7 @@ sequenceDiagram
### 1.3.2 Admin Service
* 提供配置管理接口
-* 提供配置修改、发布等接口
+* 提供配置修改、发布、检索等接口
* 接口服务对象为Portal
### 1.3.3 Meta Server
diff --git a/docs/zh/design/apollo-introduction.md b/docs/zh/design/apollo-introduction.md
index e05da35ec54..166af68c3a4 100644
--- a/docs/zh/design/apollo-introduction.md
+++ b/docs/zh/design/apollo-introduction.md
@@ -69,26 +69,30 @@ Apollo支持4个维度管理Key-Value格式的配置:
* **灰度发布**
* 支持配置的灰度发布,比如点了发布后,只对部分应用实例生效,等观察一段时间没问题后再推给所有应用实例
+* **配置项的全局视角搜索**
+ * 通过对配置项的key与value进行的模糊检索,找到拥有对应值的配置项在哪个应用、环境、集群、命名空间中被使用
+ * 通过高亮显示、分页与跳转配置等操作,便于让管理员以及SRE角色快速、便捷地找到与更改资源的配置值
+
* **权限管理、发布审核、操作审计**
- * 应用和配置的管理都有完善的权限管理机制,对配置的管理还分为了编辑和发布两个环节,从而减少人为的错误。
- * 所有的操作都有审计日志,可以方便地追踪问题
+ * 应用和配置的管理都有完善的权限管理机制,对配置的管理还分为了编辑和发布两个环节,从而减少人为的错误。
+ * 所有的操作都有审计日志,可以方便地追踪问题
* **客户端配置信息监控**
- * 可以在界面上方便地看到配置在被哪些实例使用
+ * 可以在界面上方便地看到配置在被哪些实例使用
* **提供Java和.Net原生客户端**
- * 提供了Java和.Net的原生客户端,方便应用集成
- * 支持Spring Placeholder, Annotation和Spring Boot的ConfigurationProperties,方便应用使用(需要Spring 3.1.1+)
- * 同时提供了Http接口,非Java和.Net应用也可以方便地使用
+ * 提供了Java和.Net的原生客户端,方便应用集成
+ * 支持Spring Placeholder, Annotation和Spring Boot的ConfigurationProperties,方便应用使用(需要Spring 3.1.1+)
+ * 同时提供了Http接口,非Java和.Net应用也可以方便地使用
* **提供开放平台API**
- * Apollo自身提供了比较完善的统一配置管理界面,支持多环境、多数据中心配置管理、权限、流程治理等特性。不过Apollo出于通用性考虑,不会对配置的修改做过多限制,只要符合基本的格式就能保存,不会针对不同的配置值进行针对性的校验,如数据库用户名、密码,Redis服务地址等
- * 对于这类应用配置,Apollo支持应用方通过开放平台API在Apollo进行配置的修改和发布,并且具备完善的授权和权限控制
+ * Apollo自身提供了比较完善的统一配置管理界面,支持多环境、多数据中心配置管理、权限、流程治理等特性。不过Apollo出于通用性考虑,不会对配置的修改做过多限制,只要符合基本的格式就能保存,不会针对不同的配置值进行针对性的校验,如数据库用户名、密码,Redis服务地址等
+ * 对于这类应用配置,Apollo支持应用方通过开放平台API在Apollo进行配置的修改和发布,并且具备完善的授权和权限控制
* **部署简单**
- * 配置中心作为基础服务,可用性要求非常高,这就要求Apollo对外部依赖尽可能地少
- * 目前唯一的外部依赖是MySQL,所以部署非常简单,只要安装好Java和MySQL就可以让Apollo跑起来
- * Apollo还提供了打包脚本,一键就可以生成所有需要的安装包,并且支持自定义运行时参数
+ * 配置中心作为基础服务,可用性要求非常高,这就要求Apollo对外部依赖尽可能地少
+ * 目前唯一的外部依赖是MySQL,所以部署非常简单,只要安装好Java和MySQL就可以让Apollo跑起来
+ * Apollo还提供了打包脚本,一键就可以生成所有需要的安装包,并且支持自定义运行时参数
# 3、Apollo at a glance
diff --git a/docs/zh/images/Configuration query-Non properties.png b/docs/zh/images/Configuration query-Non properties.png
new file mode 100644
index 00000000000..1a355074cbc
Binary files /dev/null and b/docs/zh/images/Configuration query-Non properties.png differ
diff --git a/docs/zh/images/Configuration query-properties.png b/docs/zh/images/Configuration query-properties.png
new file mode 100644
index 00000000000..2f8fd771109
Binary files /dev/null and b/docs/zh/images/Configuration query-properties.png differ
diff --git a/docs/zh/images/System-parameterization-of-global-search-configuration-items.png b/docs/zh/images/System-parameterization-of-global-search-configuration-items.png
new file mode 100644
index 00000000000..4f47b58cd7b
Binary files /dev/null and b/docs/zh/images/System-parameterization-of-global-search-configuration-items.png differ
diff --git a/docs/zh/portal/apollo-user-guide.md b/docs/zh/portal/apollo-user-guide.md
index 28ec5cc0fbc..cb38986bb2b 100644
--- a/docs/zh/portal/apollo-user-guide.md
+++ b/docs/zh/portal/apollo-user-guide.md
@@ -123,6 +123,20 @@ Apollo目前提供Java客户端,具体信息请点击[Java客户端使用文
Apollo中的回滚也是类似的机制,点击回滚后是将发布到客户端的配置回滚到上一个已发布版本,也就是说客户端读取到的配置会恢复到上一个版本,但页面上编辑状态的配置是不会回滚的,从而开发可以在修复配置后重新发布。
+## 1.7 配置查询(管理员权限)
+
+在配置添加或修改后,管理员用户可以通过进入 `管理员工具 - Value的全局搜索` 页面,来对配置项进行所属查询以及跳转修改。
+
+这里的查询为模糊检索,通过对配置项的key与value至少一项进行检索,找到该配置在哪个应用、环境、集群、命名空间中被使用。
+
+- properties格式配置可以直接通过对key与value进行检索
+
+![Configuration query-properties](../images/Configuration query-properties.png)
+
+- xml、json、yml、yaml、txt等格式配置,由于存储时以content-value进行存储,故可以通过key=content、value=配置项内容,进行检索
+
+![Configuration query-Non properties](../images/Configuration query-Non properties.png)
+
# 二、公共组件接入指南
## 2.1 公共组件和普通应用的区别
@@ -226,9 +240,9 @@ Apollo目前提供Java客户端,具体信息请点击[Java客户端使用文
3. 关联成功后,页面会自动跳转到Namespace权限管理页面
1. 分配修改权限
-![namespace-permission-edit](https://cdn.jsdelivr.net/gh/apolloconfig/apollo@master/doc/images/namespace-permission-edit.png)
+ ![namespace-permission-edit](https://cdn.jsdelivr.net/gh/apolloconfig/apollo@master/doc/images/namespace-permission-edit.png)
2. 分配发布权限
-![namespace-publish-permission](https://cdn.jsdelivr.net/gh/apolloconfig/apollo@master/doc/images/namespace-publish-permission.png)
+ ![namespace-publish-permission](https://cdn.jsdelivr.net/gh/apolloconfig/apollo@master/doc/images/namespace-publish-permission.png)
4. 点击“返回”回到项目页面
@@ -448,13 +462,46 @@ Apollo目前提供Java客户端,具体信息请点击[Java客户端使用文
Apollo从1.6.0版本开始增加访问密钥机制,从而只有经过身份验证的客户端才能访问敏感配置。如果应用开启了访问密钥,客户端需要配置密钥,否则无法获取配置。
1. 项目管理员打开管理密钥页面
-![管理密钥入口](https://user-images.githubusercontent.com/837658/94990081-f4d3cd80-05ab-11eb-9470-fed5ec6de92e.png)
+ ![管理密钥入口](https://user-images.githubusercontent.com/837658/94990081-f4d3cd80-05ab-11eb-9470-fed5ec6de92e.png)
2. 为项目的每个环境生成访问密钥,注意默认是禁用的,建议在客户端都配置完成后再开启
-![密钥配置页面](https://user-images.githubusercontent.com/837658/94990150-788dba00-05ac-11eb-9a12-727fdb872e42.png)
+ ![密钥配置页面](https://user-images.githubusercontent.com/837658/94990150-788dba00-05ac-11eb-9a12-727fdb872e42.png)
3. 客户端侧[配置访问密钥](zh/client/java-sdk-user-guide#_1244-配置访问密钥)
+## 6.3 全局搜索配置项的系统参数设置
+
+从2.4.0版本开始,apollo-portal增加了全局搜索配置项的功能,通过对配置项的key与value进行的模糊检索,找到拥有对应值的配置项在哪个应用、环境、集群、命名空间中被使用。为了防止在进行配置项的全局视角搜索时出现内存溢出(OOM)的问题,我们引入了一个系统参数`apollo.portal.search.perEnvMaxResults`。这个参数用于限制每个环境配置项单次最大搜索结果的数量。默认情况下,这个值被设置为`200`,但管理员可以根据实际需求进行调整。
+
+**设置方法:**
+
+1. 用超级管理员账号登录到Apollo配置中心的界面
+2. 进入`管理员工具 - 系统参数`页面新增或修改`apollo.portal.search.perEnvMaxResults`配置项即可
+
+请注意,修改系统参数可能会影响搜索功能的性能,因此在修改之前应该进行充分的测试,并确保理解参数的具体作用。
+
+![System-parameterization-of-global-search-configuration-items](../images/System-parameterization-of-global-search-configuration-items.png)
+
+
+## 6.4 appld+cluster维度下命名空间数量限制功能参数设置
+从2.4.0版本开始,apollo-portal提供了appld+cluster维度下可以创建的命名空间数量上限校验的功能,此功能默认关闭,需要配置系统 `namespace.num.limit.enabled` 开启,同时提供了系统参数`namespace.num.limit`来动态配置appld+cluster维度下的Namespace数量上限值,默认为200个,考虑到一些基础组件如网关、消息队列、Redis、数据库等需要特殊处理,新增了系统参数`namespace.num.limit.white` 来配置校验白名单,不受Namespace数量上限的影响
+
+**设置方法:**
+1. 用超级管理员账号登录到Apollo配置中心的界面
+2. 进入 `管理员工具 - 系统参数 - ConfigDB 配置管理` 页面新增或修改 `namespace.num.limit.enabled` 配置项为true/false 即可开启/关闭此功能,默认关闭
+
+ ![item-num-limit-enabled](https://cdn.jsdelivr.net/gh/apolloconfig/apollo@master/doc/images/namespace-num-limit-enabled.png)
+
+3. 进入 `管理员工具 - 系统参数 - ConfigDB 配置管理` 页面新增或修改 `namespace.num.limit` 配置项来配置单个appld+cluster下的namespace数量上限值,默认为200
+
+ ![item-num-limit](https://cdn.jsdelivr.net/gh/apolloconfig/apollo@master/doc/images/namespace-num-limit.png)
+
+4. 进入 `管理员工具 - 系统参数 - ConfigDB 配置管理` 页面新增或修改 `namespace.num.limit.white` 配置项来配置namespace数量上限校验的白名单,多个AppId使用英文逗号分隔
+
+ ![item-num-limit](https://cdn.jsdelivr.net/gh/apolloconfig/apollo@master/doc/images/namespace-num-limit-white.png)
+
+
+
# 七、最佳实践
## 7.1 安全相关
@@ -485,4 +532,4 @@ Apollo 支持细粒度的权限控制,请务必根据实际情况做好权限
1. `apollo-configservice`和`apollo-adminservice`是基于内网可信网络设计的,所以出于安全考虑,禁止`apollo-configservice`和`apollo-adminservice`直接暴露在公网
2. 对敏感配置可以考虑开启[访问秘钥](#_62-%e9%85%8d%e7%bd%ae%e8%ae%bf%e9%97%ae%e5%af%86%e9%92%a5),从而只有经过身份验证的客户端才能访问敏感配置
3. 1.7.1及以上版本可以考虑为`apollo-adminservice`开启[访问控制](zh/deployment/distributed-deployment-guide?id=_326-admin-serviceaccesscontrolenabled-配置apollo-adminservice是否开启访问控制),从而只有[受控的](zh/deployment/distributed-deployment-guide?id=_3112-admin-serviceaccesstokens-设置apollo-portal访问各环境apollo-adminservice所需的access-token)`apollo-portal`才能访问对应接口,增强安全性
-4. 2.1.0及以上版本可以考虑为`eureka`开启[访问控制](zh/deployment/distributed-deployment-guide?id=_329-apolloeurekaserversecurityenabled-配置是否开启eureka-server的登录认证),从而只有受控的`apollo-configservice`和`apollo-adminservice`可以注册到`eureka`,增强安全性
\ No newline at end of file
+4. 2.1.0及以上版本可以考虑为`eureka`开启[访问控制](zh/deployment/distributed-deployment-guide?id=_329-apolloeurekaserversecurityenabled-配置是否开启eureka-server的登录认证),从而只有受控的`apollo-configservice`和`apollo-adminservice`可以注册到`eureka`,增强安全性
diff --git a/pom.xml b/pom.xml
index 7ffab97f930..465a1c01343 100644
--- a/pom.xml
+++ b/pom.xml
@@ -78,7 +78,7 @@
5.9.21.4.0
- 8.0.32
+ 8.2.042.7.23.3.0
diff --git a/scripts/sql/profiles/h2-default/apolloconfigdb.sql b/scripts/sql/profiles/h2-default/apolloconfigdb.sql
index 8a24f1c82c9..9fb40f0c21f 100644
--- a/scripts/sql/profiles/h2-default/apolloconfigdb.sql
+++ b/scripts/sql/profiles/h2-default/apolloconfigdb.sql
@@ -393,6 +393,7 @@ CREATE TABLE `AccessKey` (
`Id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`AppId` varchar(64) NOT NULL DEFAULT 'default' COMMENT 'AppID',
`Secret` varchar(128) NOT NULL DEFAULT '' COMMENT 'Secret',
+ `Mode` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '密钥模式,0: filter,1: observer',
`IsEnabled` boolean NOT NULL DEFAULT FALSE COMMENT '1: enabled, 0: disabled',
`IsDeleted` boolean NOT NULL DEFAULT FALSE COMMENT '1: deleted, 0: normal',
`DeletedAt` BIGINT(20) NOT NULL DEFAULT '0' COMMENT 'Delete timestamp based on milliseconds',
diff --git a/scripts/sql/profiles/h2-default/delta/v230-v240/apolloconfigdb-v230-v240.sql b/scripts/sql/profiles/h2-default/delta/v230-v240/apolloconfigdb-v230-v240.sql
new file mode 100644
index 00000000000..459c12ff9b4
--- /dev/null
+++ b/scripts/sql/profiles/h2-default/delta/v230-v240/apolloconfigdb-v230-v240.sql
@@ -0,0 +1,43 @@
+--
+-- Copyright 2024 Apollo Authors
+--
+-- Licensed 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.
+--
+-- delta schema to upgrade apollo config db from v2.3.0 to v2.4.0
+
+--
+-- ===============================================================================
+-- == ==
+-- == Generated from 'scripts/sql/src/' ==
+-- == by running 'mvn compile -pl apollo-build-sql-converter -Psql-converter'. ==
+-- == DO NOT EDIT !!! ==
+-- == ==
+-- ===============================================================================
+--
+
+-- H2 Function
+-- ------------------------------------------------------------
+CREATE ALIAS IF NOT EXISTS UNIX_TIMESTAMP FOR "com.ctrip.framework.apollo.common.jpa.H2Function.unixTimestamp";
+
+--
+
+ALTER TABLE `AccessKey` ADD COLUMN `Mode` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '密钥模式,0: filter,1: observer' AFTER `Secret`;
+
+--
+-- ===============================================================================
+-- == ==
+-- == Generated from 'scripts/sql/src/' ==
+-- == by running 'mvn compile -pl apollo-build-sql-converter -Psql-converter'. ==
+-- == DO NOT EDIT !!! ==
+-- == ==
+-- ===============================================================================
diff --git a/scripts/sql/profiles/mysql-database-not-specified/apolloconfigdb.sql b/scripts/sql/profiles/mysql-database-not-specified/apolloconfigdb.sql
index 4d2e0c19118..dd9b4dcae8e 100644
--- a/scripts/sql/profiles/mysql-database-not-specified/apolloconfigdb.sql
+++ b/scripts/sql/profiles/mysql-database-not-specified/apolloconfigdb.sql
@@ -404,6 +404,7 @@ CREATE TABLE `AccessKey` (
`Id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`AppId` varchar(64) NOT NULL DEFAULT 'default' COMMENT 'AppID',
`Secret` varchar(128) NOT NULL DEFAULT '' COMMENT 'Secret',
+ `Mode` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '密钥模式,0: filter,1: observer',
`IsEnabled` bit(1) NOT NULL DEFAULT b'0' COMMENT '1: enabled, 0: disabled',
`IsDeleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '1: deleted, 0: normal',
`DeletedAt` BIGINT(20) NOT NULL DEFAULT '0' COMMENT 'Delete timestamp based on milliseconds',
diff --git a/scripts/sql/profiles/mysql-database-not-specified/delta/v230-v240/apolloconfigdb-v230-v240.sql b/scripts/sql/profiles/mysql-database-not-specified/delta/v230-v240/apolloconfigdb-v230-v240.sql
new file mode 100644
index 00000000000..c71b792aa6e
--- /dev/null
+++ b/scripts/sql/profiles/mysql-database-not-specified/delta/v230-v240/apolloconfigdb-v230-v240.sql
@@ -0,0 +1,39 @@
+--
+-- Copyright 2024 Apollo Authors
+--
+-- Licensed 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.
+--
+-- delta schema to upgrade apollo config db from v2.3.0 to v2.4.0
+
+--
+-- ===============================================================================
+-- == ==
+-- == Generated from 'scripts/sql/src/' ==
+-- == by running 'mvn compile -pl apollo-build-sql-converter -Psql-converter'. ==
+-- == DO NOT EDIT !!! ==
+-- == ==
+-- ===============================================================================
+--
+--
+
+ALTER TABLE `AccessKey`
+ ADD COLUMN `Mode` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '密钥模式,0: filter,1: observer' AFTER `Secret`;
+
+--
+-- ===============================================================================
+-- == ==
+-- == Generated from 'scripts/sql/src/' ==
+-- == by running 'mvn compile -pl apollo-build-sql-converter -Psql-converter'. ==
+-- == DO NOT EDIT !!! ==
+-- == ==
+-- ===============================================================================
diff --git a/scripts/sql/profiles/mysql-default/apolloconfigdb.sql b/scripts/sql/profiles/mysql-default/apolloconfigdb.sql
index 3736ea599f3..9416af7380a 100644
--- a/scripts/sql/profiles/mysql-default/apolloconfigdb.sql
+++ b/scripts/sql/profiles/mysql-default/apolloconfigdb.sql
@@ -409,6 +409,7 @@ CREATE TABLE `AccessKey` (
`Id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`AppId` varchar(64) NOT NULL DEFAULT 'default' COMMENT 'AppID',
`Secret` varchar(128) NOT NULL DEFAULT '' COMMENT 'Secret',
+ `Mode` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '密钥模式,0: filter,1: observer',
`IsEnabled` bit(1) NOT NULL DEFAULT b'0' COMMENT '1: enabled, 0: disabled',
`IsDeleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '1: deleted, 0: normal',
`DeletedAt` BIGINT(20) NOT NULL DEFAULT '0' COMMENT 'Delete timestamp based on milliseconds',
diff --git a/scripts/sql/profiles/mysql-default/delta/v230-v240/apolloconfigdb-v230-v240.sql b/scripts/sql/profiles/mysql-default/delta/v230-v240/apolloconfigdb-v230-v240.sql
new file mode 100644
index 00000000000..8bb5fdc1a0e
--- /dev/null
+++ b/scripts/sql/profiles/mysql-default/delta/v230-v240/apolloconfigdb-v230-v240.sql
@@ -0,0 +1,41 @@
+--
+-- Copyright 2024 Apollo Authors
+--
+-- Licensed 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.
+--
+-- delta schema to upgrade apollo config db from v2.3.0 to v2.4.0
+
+--
+-- ===============================================================================
+-- == ==
+-- == Generated from 'scripts/sql/src/' ==
+-- == by running 'mvn compile -pl apollo-build-sql-converter -Psql-converter'. ==
+-- == DO NOT EDIT !!! ==
+-- == ==
+-- ===============================================================================
+--
+--
+-- Use Database
+Use ApolloConfigDB;
+
+ALTER TABLE `AccessKey`
+ ADD COLUMN `Mode` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '密钥模式,0: filter,1: observer' AFTER `Secret`;
+
+--
+-- ===============================================================================
+-- == ==
+-- == Generated from 'scripts/sql/src/' ==
+-- == by running 'mvn compile -pl apollo-build-sql-converter -Psql-converter'. ==
+-- == DO NOT EDIT !!! ==
+-- == ==
+-- ===============================================================================
diff --git a/scripts/sql/src/apolloconfigdb.sql b/scripts/sql/src/apolloconfigdb.sql
index 9f85a8791ce..216dfdd9a33 100644
--- a/scripts/sql/src/apolloconfigdb.sql
+++ b/scripts/sql/src/apolloconfigdb.sql
@@ -397,6 +397,7 @@ CREATE TABLE `AccessKey` (
`Id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`AppId` varchar(64) NOT NULL DEFAULT 'default' COMMENT 'AppID',
`Secret` varchar(128) NOT NULL DEFAULT '' COMMENT 'Secret',
+ `Mode` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '密钥模式,0: filter,1: observer',
`IsEnabled` bit(1) NOT NULL DEFAULT b'0' COMMENT '1: enabled, 0: disabled',
`IsDeleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '1: deleted, 0: normal',
`DeletedAt` BIGINT(20) NOT NULL DEFAULT '0' COMMENT 'Delete timestamp based on milliseconds',
diff --git a/scripts/sql/src/delta/v230-v240/apolloconfigdb-v230-v240.sql b/scripts/sql/src/delta/v230-v240/apolloconfigdb-v230-v240.sql
new file mode 100644
index 00000000000..2e3cddfbbea
--- /dev/null
+++ b/scripts/sql/src/delta/v230-v240/apolloconfigdb-v230-v240.sql
@@ -0,0 +1,25 @@
+--
+-- Copyright 2024 Apollo Authors
+--
+-- Licensed 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.
+--
+-- delta schema to upgrade apollo config db from v2.3.0 to v2.4.0
+
+-- ${gists.autoGeneratedDeclaration}
+-- ${gists.h2Function}
+-- ${gists.useDatabase}
+
+ALTER TABLE `AccessKey`
+ ADD COLUMN `Mode` tinyint unsigned NOT NULL DEFAULT '0' COMMENT '密钥模式,0: filter,1: observer' AFTER `Secret`;
+
+-- ${gists.autoGeneratedDeclaration}