This is an automated email from the ASF dual-hosted git repository.
zrlw pushed a commit to branch 3.3
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.3 by this push:
new bc543b67de Support method level TPS in `DefaultTPSLimiter` (#15679)
bc543b67de is described below
commit bc543b67dec9eb6819bfccb87178a52907b6233d
Author: Faye Lin <[email protected]>
AuthorDate: Thu Sep 18 15:45:21 2025 +0800
Support method level TPS in `DefaultTPSLimiter` (#15679)
---
.../dubbo/rpc/filter/tps/DefaultTPSLimiter.java | 21 ++++++-----
.../rpc/filter/tps/DefaultTPSLimiterTest.java | 42 +++++++++++++++++++++-
2 files changed, 54 insertions(+), 9 deletions(-)
diff --git
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/tps/DefaultTPSLimiter.java
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/tps/DefaultTPSLimiter.java
index 645345db3f..0ebd8856fb 100644
---
a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/tps/DefaultTPSLimiter.java
+++
b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/tps/DefaultTPSLimiter.java
@@ -39,27 +39,32 @@ public class DefaultTPSLimiter implements TPSLimiter {
@Override
public boolean isAllowable(URL url, Invocation invocation) {
+ boolean isMethodLevelTpsConfigured =
+ url.hasMethodParameter(RpcUtils.getMethodName(invocation),
TPS_LIMIT_RATE_KEY);
+ String key = isMethodLevelTpsConfigured
+ ? url.getServiceKey() + "#" +
RpcUtils.getMethodName(invocation)
+ : url.getServiceKey();
int rate = url.getMethodParameter(RpcUtils.getMethodName(invocation),
TPS_LIMIT_RATE_KEY, -1);
long interval = url.getMethodParameter(
RpcUtils.getMethodName(invocation), TPS_LIMIT_INTERVAL_KEY,
DEFAULT_TPS_LIMIT_INTERVAL);
- String serviceKey = url.getServiceKey();
+
if (rate > 0) {
- StatItem statItem = stats.get(serviceKey);
+ StatItem statItem = stats.get(key);
if (statItem == null) {
- stats.putIfAbsent(serviceKey, new StatItem(serviceKey, rate,
interval));
- statItem = stats.get(serviceKey);
+ stats.putIfAbsent(key, new StatItem(key, rate, interval));
+ statItem = stats.get(key);
} else {
// rate or interval has changed, rebuild
if (statItem.getRate() != rate || statItem.getInterval() !=
interval) {
- stats.put(serviceKey, new StatItem(serviceKey, rate,
interval));
- statItem = stats.get(serviceKey);
+ stats.put(key, new StatItem(key, rate, interval));
+ statItem = stats.get(key);
}
}
return statItem.isAllowable();
} else {
- StatItem statItem = stats.get(serviceKey);
+ StatItem statItem = stats.get(key);
if (statItem != null) {
- stats.remove(serviceKey);
+ stats.remove(key);
}
}
diff --git
a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/tps/DefaultTPSLimiterTest.java
b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/tps/DefaultTPSLimiterTest.java
index 188631f8dc..6c6219967d 100644
---
a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/tps/DefaultTPSLimiterTest.java
+++
b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/tps/DefaultTPSLimiterTest.java
@@ -65,12 +65,52 @@ class DefaultTPSLimiterTest {
}
@Test
- void testTPSLimiterForMethodLevelConfig() {
+ void testMethodLevelTpsOverridesServiceLevel() {
Invocation invocation = new MockInvocation();
URL url = URL.valueOf("test://test");
url = url.addParameter(INTERFACE_KEY,
"org.apache.dubbo.rpc.file.TpsService");
url = url.addParameter(TPS_LIMIT_RATE_KEY, TEST_LIMIT_RATE);
int tpsConfigForMethodLevel = 3;
+ url = url.addParameter("tps", 1);
+ url = url.addParameter("echo.tps", tpsConfigForMethodLevel);
+ url = url.addParameter(TPS_LIMIT_INTERVAL_KEY, 1000);
+ for (int i = 1; i <= tpsConfigForMethodLevel + 1; i++) {
+ if (i == tpsConfigForMethodLevel + 1) {
+ Assertions.assertFalse(defaultTPSLimiter.isAllowable(url,
invocation));
+ } else {
+ Assertions.assertTrue(defaultTPSLimiter.isAllowable(url,
invocation));
+ }
+ }
+ }
+
+ @Test
+ void testServiceLevelTpsWhenOtherMethodsHaveTps() {
+ Invocation invocation = new MockInvocation();
+ URL url = URL.valueOf("test://test");
+ url = url.addParameter(INTERFACE_KEY,
"org.apache.dubbo.rpc.file.TpsService");
+ url = url.addParameter(TPS_LIMIT_RATE_KEY, TEST_LIMIT_RATE);
+ int tpsConfigForServiceLevel = 3;
+ url = url.addParameter("tps", tpsConfigForServiceLevel);
+ url = url.addParameter("otherMethod.tps", 1);
+ url = url.addParameter(TPS_LIMIT_INTERVAL_KEY, 1000);
+ for (int i = 1; i <= tpsConfigForServiceLevel + 1; i++) {
+ if (i == tpsConfigForServiceLevel + 1) {
+ Assertions.assertFalse(defaultTPSLimiter.isAllowable(url,
invocation));
+ } else {
+ Assertions.assertTrue(defaultTPSLimiter.isAllowable(url,
invocation));
+ }
+ }
+ }
+
+ @Test
+ void testMethodLevelTpsIsolation() {
+ Invocation invocation = new MockInvocation();
+ URL url = URL.valueOf("test://test");
+ url = url.addParameter(INTERFACE_KEY,
"org.apache.dubbo.rpc.file.TpsService");
+ url = url.addParameter(TPS_LIMIT_RATE_KEY, TEST_LIMIT_RATE);
+ int tpsConfigForMethodLevel = 3;
+ url = url.addParameter("tps", 1);
+ url = url.addParameter("otherMethod.tps", 2);
url = url.addParameter("echo.tps", tpsConfigForMethodLevel);
url = url.addParameter(TPS_LIMIT_INTERVAL_KEY, 1000);
for (int i = 1; i <= tpsConfigForMethodLevel + 1; i++) {