Skip to content

Commit bc543b6

Browse files
authored
Support method level TPS in DefaultTPSLimiter (#15679)
1 parent 956a47b commit bc543b6

File tree

2 files changed

+54
-9
lines changed

2 files changed

+54
-9
lines changed

dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/tps/DefaultTPSLimiter.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,27 +39,32 @@ public class DefaultTPSLimiter implements TPSLimiter {
3939

4040
@Override
4141
public boolean isAllowable(URL url, Invocation invocation) {
42+
boolean isMethodLevelTpsConfigured =
43+
url.hasMethodParameter(RpcUtils.getMethodName(invocation), TPS_LIMIT_RATE_KEY);
44+
String key = isMethodLevelTpsConfigured
45+
? url.getServiceKey() + "#" + RpcUtils.getMethodName(invocation)
46+
: url.getServiceKey();
4247
int rate = url.getMethodParameter(RpcUtils.getMethodName(invocation), TPS_LIMIT_RATE_KEY, -1);
4348
long interval = url.getMethodParameter(
4449
RpcUtils.getMethodName(invocation), TPS_LIMIT_INTERVAL_KEY, DEFAULT_TPS_LIMIT_INTERVAL);
45-
String serviceKey = url.getServiceKey();
50+
4651
if (rate > 0) {
47-
StatItem statItem = stats.get(serviceKey);
52+
StatItem statItem = stats.get(key);
4853
if (statItem == null) {
49-
stats.putIfAbsent(serviceKey, new StatItem(serviceKey, rate, interval));
50-
statItem = stats.get(serviceKey);
54+
stats.putIfAbsent(key, new StatItem(key, rate, interval));
55+
statItem = stats.get(key);
5156
} else {
5257
// rate or interval has changed, rebuild
5358
if (statItem.getRate() != rate || statItem.getInterval() != interval) {
54-
stats.put(serviceKey, new StatItem(serviceKey, rate, interval));
55-
statItem = stats.get(serviceKey);
59+
stats.put(key, new StatItem(key, rate, interval));
60+
statItem = stats.get(key);
5661
}
5762
}
5863
return statItem.isAllowable();
5964
} else {
60-
StatItem statItem = stats.get(serviceKey);
65+
StatItem statItem = stats.get(key);
6166
if (statItem != null) {
62-
stats.remove(serviceKey);
67+
stats.remove(key);
6368
}
6469
}
6570

dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/tps/DefaultTPSLimiterTest.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,52 @@ void testIsNotAllowable() {
6565
}
6666

6767
@Test
68-
void testTPSLimiterForMethodLevelConfig() {
68+
void testMethodLevelTpsOverridesServiceLevel() {
6969
Invocation invocation = new MockInvocation();
7070
URL url = URL.valueOf("test://test");
7171
url = url.addParameter(INTERFACE_KEY, "org.apache.dubbo.rpc.file.TpsService");
7272
url = url.addParameter(TPS_LIMIT_RATE_KEY, TEST_LIMIT_RATE);
7373
int tpsConfigForMethodLevel = 3;
74+
url = url.addParameter("tps", 1);
75+
url = url.addParameter("echo.tps", tpsConfigForMethodLevel);
76+
url = url.addParameter(TPS_LIMIT_INTERVAL_KEY, 1000);
77+
for (int i = 1; i <= tpsConfigForMethodLevel + 1; i++) {
78+
if (i == tpsConfigForMethodLevel + 1) {
79+
Assertions.assertFalse(defaultTPSLimiter.isAllowable(url, invocation));
80+
} else {
81+
Assertions.assertTrue(defaultTPSLimiter.isAllowable(url, invocation));
82+
}
83+
}
84+
}
85+
86+
@Test
87+
void testServiceLevelTpsWhenOtherMethodsHaveTps() {
88+
Invocation invocation = new MockInvocation();
89+
URL url = URL.valueOf("test://test");
90+
url = url.addParameter(INTERFACE_KEY, "org.apache.dubbo.rpc.file.TpsService");
91+
url = url.addParameter(TPS_LIMIT_RATE_KEY, TEST_LIMIT_RATE);
92+
int tpsConfigForServiceLevel = 3;
93+
url = url.addParameter("tps", tpsConfigForServiceLevel);
94+
url = url.addParameter("otherMethod.tps", 1);
95+
url = url.addParameter(TPS_LIMIT_INTERVAL_KEY, 1000);
96+
for (int i = 1; i <= tpsConfigForServiceLevel + 1; i++) {
97+
if (i == tpsConfigForServiceLevel + 1) {
98+
Assertions.assertFalse(defaultTPSLimiter.isAllowable(url, invocation));
99+
} else {
100+
Assertions.assertTrue(defaultTPSLimiter.isAllowable(url, invocation));
101+
}
102+
}
103+
}
104+
105+
@Test
106+
void testMethodLevelTpsIsolation() {
107+
Invocation invocation = new MockInvocation();
108+
URL url = URL.valueOf("test://test");
109+
url = url.addParameter(INTERFACE_KEY, "org.apache.dubbo.rpc.file.TpsService");
110+
url = url.addParameter(TPS_LIMIT_RATE_KEY, TEST_LIMIT_RATE);
111+
int tpsConfigForMethodLevel = 3;
112+
url = url.addParameter("tps", 1);
113+
url = url.addParameter("otherMethod.tps", 2);
74114
url = url.addParameter("echo.tps", tpsConfigForMethodLevel);
75115
url = url.addParameter(TPS_LIMIT_INTERVAL_KEY, 1000);
76116
for (int i = 1; i <= tpsConfigForMethodLevel + 1; i++) {

0 commit comments

Comments
 (0)