This is an automated email from the ASF dual-hosted git repository.
lizhimins pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git
The following commit(s) were added to refs/heads/rocketmq-studio by this push:
new 613c3b675 fix(lite): keep the LiteTopic list and quota pages up when
one master fails (#4566)
613c3b675 is described below
commit 613c3b675091ff74c600b87c693cdde0523e2011
Author: 烤化の初雪 <[email protected]>
AuthorDate: Thu Sep 24 17:45:04 2026 +0800
fix(lite): keep the LiteTopic list and quota pages up when one master fails
(#4566)
fix(lite): keep the LiteTopic list and quota pages up when one master fails
getBrokerLiteInfo was the only per-master read in the provider without
a catch, so one unreachable or pre-lite master failed the whole admin
action and surfaced as a 502 for the entire list and quota pages even
when every other master answered. Skip the failing master and aggregate
the reachable ones, matching the degradation every sibling read in the
file already applies.
Fixes #4565.
---
.../provider/apache/RocketMQLiteTopicProvider.java | 21 ++++++++++-
.../apache/RocketMQLiteTopicProviderTest.java | 44 ++++++++++++++++++++++
2 files changed, 63 insertions(+), 2 deletions(-)
diff --git
a/server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQLiteTopicProvider.java
b/server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQLiteTopicProvider.java
index cfae98e34..73042a056 100644
---
a/server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQLiteTopicProvider.java
+++
b/server/src/main/java/org/apache/rocketmq/studio/provider/apache/RocketMQLiteTopicProvider.java
@@ -162,7 +162,16 @@ public class RocketMQLiteTopicProvider implements
LiteTopicProvider {
throws Exception {
Map<String, ParentTopicAccumulator> parents = new LinkedHashMap<>();
for (String master : masters) {
- GetBrokerLiteInfoResponseBody info =
admin.getBrokerLiteInfo(master);
+ final GetBrokerLiteInfoResponseBody info;
+ try {
+ info = admin.getBrokerLiteInfo(master);
+ } catch (Exception failure) {
+ // Every other per-master read in this provider degrades
instead of failing
+ // the page; a single unreachable (or pre-lite) master must
not turn the
+ // whole list into a 502 when its peers still answer.
+ log.warn("Skipping master {} for the LiteTopic list: {}",
master, failure.getMessage());
+ continue;
+ }
if (info == null || info.getTopicMeta() == null) {
continue;
}
@@ -422,7 +431,15 @@ public class RocketMQLiteTopicProvider implements
LiteTopicProvider {
long currentSessions = 0;
long maxSessions = 0;
for (String master : masters) {
- GetBrokerLiteInfoResponseBody info =
admin.getBrokerLiteInfo(master);
+ final GetBrokerLiteInfoResponseBody info;
+ try {
+ info = admin.getBrokerLiteInfo(master);
+ } catch (Exception failure) {
+ // Same per-master degradation as the list path: one
unreachable or
+ // pre-lite master must not fail the whole quota page with
a 502.
+ log.warn("Skipping master {} for the LiteTopic quota: {}",
master, failure.getMessage());
+ continue;
+ }
if (info == null) {
// Skip the master entirely: adding its session cap
without its current
// counts would build the ratio out of two different
master sets.
diff --git
a/server/src/test/java/org/apache/rocketmq/studio/provider/apache/RocketMQLiteTopicProviderTest.java
b/server/src/test/java/org/apache/rocketmq/studio/provider/apache/RocketMQLiteTopicProviderTest.java
index a6518fd88..009edba67 100644
---
a/server/src/test/java/org/apache/rocketmq/studio/provider/apache/RocketMQLiteTopicProviderTest.java
+++
b/server/src/test/java/org/apache/rocketmq/studio/provider/apache/RocketMQLiteTopicProviderTest.java
@@ -124,6 +124,50 @@ class RocketMQLiteTopicProviderTest {
assertThat(provider.isSupported()).isTrue();
}
+ @Test
+ void listLiteTopicsSkipsAMasterWhoseLiteInfoFailsInsteadOfFailingThePage()
throws Exception {
+ String failingMaster = "127.0.0.1:10912";
+ when(admin.examineBrokerClusterInfo()).thenReturn(cluster(BROKER_A,
failingMaster));
+
when(admin.getBrokerLiteInfo(BROKER_A)).thenReturn(brokerLiteInfo(PARENT, 30,
2, GROUP));
+ when(admin.getBrokerLiteInfo(failingMaster))
+ .thenThrow(new IllegalStateException("broker restarting"));
+ when(admin.getParentTopicInfo(BROKER_A,
PARENT)).thenReturn(parentTopicInfo(PARENT, 30, 2));
+ when(admin.getLiteGroupInfo(BROKER_A, GROUP, null,
1)).thenReturn(lag(7));
+
when(admin.examineConsumerConnectionInfo(GROUP)).thenReturn(consumerConnection("c1",
"10.0.0.9:1234"));
+ when(admin.getLiteClientInfo(BROKER_A, PARENT, GROUP,
"c1")).thenReturn(clientInfo(2, System.currentTimeMillis()));
+
+ List<LiteTopicSummary> summaries = provider.listLiteTopics(null, null);
+
+ assertThat(summaries).singleElement().satisfies(summary -> {
+ assertThat(summary.getTopicPattern()).isEqualTo(PARENT);
+ assertThat(summary.getTopicCount()).isEqualTo(2);
+ assertThat(summary.getTotalBacklog()).isEqualTo(7L);
+ });
+ }
+
+ @Test
+ void quotaSkipsAMasterWhoseLiteInfoFailsInsteadOfFailingThePage() throws
Exception {
+ String failingMaster = "127.0.0.1:10912";
+ when(admin.examineBrokerClusterInfo()).thenReturn(cluster(BROKER_A,
failingMaster));
+ when(admin.getBrokerLiteInfo(BROKER_A)).thenReturn(brokerLiteInfo(3,
40, 3));
+ when(admin.getBrokerLiteInfo(failingMaster))
+ .thenThrow(new IllegalStateException("broker restarting"));
+ Properties reachableConfig = new Properties();
+ reachableConfig.setProperty("maxLiteSubscriptionCount", "100000");
+ when(admin.getBrokerConfig(BROKER_A)).thenReturn(reachableConfig);
+ Properties failingConfig = new Properties();
+ failingConfig.setProperty("maxLiteSubscriptionCount", "100000");
+ when(admin.getBrokerConfig(failingMaster)).thenReturn(failingConfig);
+
+ LiteTopicQuota quota = provider.getQuota(null);
+
+ // Only the reachable master contributed counts, so the ratio is built
from it alone.
+ assertThat(quota.getCurrentTopicCount()).isEqualTo(3);
+ assertThat(quota.getMaxTopicCount()).isEqualTo(40);
+ assertThat(quota.getCurrentSessionCount()).isEqualTo(3);
+ assertThat(quota.getMaxSessionCount()).isEqualTo(100_000);
+ }
+
@Test
void listLiteTopicsAggregatesParentTopicTtlBacklogAndSessions() throws
Exception {
long lastAccess = System.currentTimeMillis() - 1_000;