Skip to content

Commit 50082a1

Browse files
committed
feat(net): add global rate limiter function
1 parent ecbb194 commit 50082a1

7 files changed

Lines changed: 67 additions & 2 deletions

File tree

common/src/main/java/org/tron/common/parameter/CommonParameter.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,12 @@ public class CommonParameter {
398398
@Setter
399399
public RateLimiterInitialization rateLimiterInitialization;
400400
@Getter
401+
@Setter
402+
public int rateLimiterGlobalQps;
403+
@Getter
404+
@Setter
405+
public int rateLimiterGlobalIpQps;
406+
@Getter
401407
public DbBackupConfig dbBackupConfig;
402408
@Getter
403409
public RocksDbSettings rocksDBCustomSettings;

common/src/main/java/org/tron/core/Constant.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,10 @@ public class Constant {
235235

236236
public static final String RATE_LIMITER = "rate.limiter";
237237

238+
public static final String RATE_LIMITER_GLOBAL_QPS = "rate.limiter.global.qps";
239+
240+
public static final String RATE_LIMITER_GLOBAL_IP_QPS = "rate.limiter.global.ip.qps";
241+
238242
public static final String COMMITTEE_CHANGED_DELEGATION = "committee.changedDelegation";
239243

240244
public static final String CRYPTO_ENGINE = "crypto.engine";

framework/src/main/java/org/tron/core/config/args/Args.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ public static void clearParam() {
221221
PARAMETER.allowNewRewardAlgorithm = 0;
222222
PARAMETER.allowNewReward = 0;
223223
PARAMETER.memoFee = 0;
224+
PARAMETER.rateLimiterGlobalQps = 3000;
225+
PARAMETER.rateLimiterGlobalIpQps = 30;
224226
}
225227

226228
/**
@@ -927,6 +929,14 @@ public static void setParam(final String[] args, final String confFileName) {
927929
PARAMETER.fullNodeAllowShieldedTransactionArgs = true;
928930
}
929931

932+
PARAMETER.rateLimiterGlobalQps =
933+
config.hasPath(Constant.RATE_LIMITER_GLOBAL_QPS) ? config
934+
.getInt(Constant.RATE_LIMITER_GLOBAL_QPS) : 3000;
935+
936+
PARAMETER.rateLimiterGlobalIpQps =
937+
config.hasPath(Constant.RATE_LIMITER_GLOBAL_IP_QPS) ? config
938+
.getInt(Constant.RATE_LIMITER_GLOBAL_IP_QPS) : 30;
939+
930940
PARAMETER.rateLimiterInitialization =
931941
config.hasPath(Constant.RATE_LIMITER) ? getRateLimiterFromConfig(config)
932942
: new RateLimiterInitialization();

framework/src/main/java/org/tron/core/services/http/RateLimiterServlet.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.tron.common.prometheus.MetricLabels;
1717
import org.tron.common.prometheus.Metrics;
1818
import org.tron.core.config.args.Args;
19+
import org.tron.core.services.ratelimiter.GlobalRateLimiter;
1920
import org.tron.core.services.ratelimiter.RateLimiterContainer;
2021
import org.tron.core.services.ratelimiter.RuntimeData;
2122
import org.tron.core.services.ratelimiter.adapter.DefaultBaseQqsAdapter;
@@ -91,12 +92,16 @@ private void addRateContainer() {
9192
@Override
9293
protected void service(HttpServletRequest req, HttpServletResponse resp)
9394
throws ServletException, IOException {
95+
96+
RuntimeData runtimeData = new RuntimeData(req);
97+
GlobalRateLimiter.acquire(runtimeData);
98+
9499
IRateLimiter rateLimiter = container.get(KEY_PREFIX_HTTP, getClass().getSimpleName());
95100

96101
boolean acquireResource = true;
97102

98103
if (rateLimiter != null) {
99-
acquireResource = rateLimiter.acquire(new RuntimeData(req));
104+
acquireResource = rateLimiter.acquire(runtimeData);
100105
}
101106
String url = Strings.isNullOrEmpty(req.getRequestURI())
102107
? MetricLabels.UNDEFINED : req.getRequestURI();
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package org.tron.core.services.ratelimiter;
2+
3+
import com.google.common.base.Strings;
4+
import com.google.common.cache.Cache;
5+
import com.google.common.cache.CacheBuilder;
6+
import com.google.common.util.concurrent.RateLimiter;
7+
import java.util.concurrent.TimeUnit;
8+
import org.tron.core.config.args.Args;
9+
10+
public class GlobalRateLimiter {
11+
12+
private static double QPS = Args.getInstance().getRateLimiterGlobalQps();
13+
14+
private static double IP_QPS = Args.getInstance().getRateLimiterGlobalIpQps();
15+
16+
private static Cache<String, RateLimiter> cache = CacheBuilder.newBuilder()
17+
.maximumSize(10000).expireAfterWrite(1, TimeUnit.HOURS).build();
18+
19+
private static RateLimiter rateLimiter = RateLimiter.create(QPS);
20+
21+
public static void acquire(RuntimeData runtimeData) {
22+
rateLimiter.acquire();
23+
String ip = runtimeData.getRemoteAddr();
24+
if (Strings.isNullOrEmpty(ip)) {
25+
return;
26+
}
27+
RateLimiter r = cache.getIfPresent(ip);
28+
if (r == null) {
29+
r = RateLimiter.create(IP_QPS);
30+
cache.put(ip, r);
31+
}
32+
r.acquire();
33+
}
34+
35+
}

framework/src/main/java/org/tron/core/services/ratelimiter/RateLimiterInterceptor.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,13 @@ public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
107107
IRateLimiter rateLimiter = container
108108
.get(KEY_PREFIX_RPC, call.getMethodDescriptor().getFullMethodName());
109109

110+
RuntimeData runtimeData = new RuntimeData(call);
111+
GlobalRateLimiter.acquire(runtimeData);
112+
110113
boolean acquireResource = true;
111114

112115
if (rateLimiter != null) {
113-
acquireResource = rateLimiter.acquire(new RuntimeData(call));
116+
acquireResource = rateLimiter.acquire(runtimeData);
114117
}
115118

116119
Listener<ReqT> listener = new ServerCall.Listener<ReqT>() {

framework/src/test/java/org/tron/common/config/args/ArgsTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,7 @@ public void testConfig() {
3030
Assert.assertEquals(Args.getInstance().getNodeDiscoveryPingTimeout(), 15_000);
3131
Assert.assertEquals(Args.getInstance().getMaxFastForwardNum(), 3);
3232
Assert.assertEquals(Args.getInstance().getBlockCacheTimeout(), 60);
33+
Assert.assertEquals(Args.getInstance().getRateLimiterGlobalQps(), 3000);
34+
Assert.assertEquals(Args.getInstance().getRateLimiterGlobalIpQps(), 30);
3335
}
3436
}

0 commit comments

Comments
 (0)