Skip to content

Commit 2b7588c

Browse files
authored
Merge pull request #5093 from wubin01/rate-limit
feat(net): add global rate limiter function
2 parents c1fe7ad + dc63ec1 commit 2b7588c

8 files changed

Lines changed: 91 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: 12 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 = 50000;
225+
PARAMETER.rateLimiterGlobalIpQps = 10000;
224226
PARAMETER.p2pDisable = false;
225227
}
226228

@@ -928,6 +930,14 @@ public static void setParam(final String[] args, final String confFileName) {
928930
PARAMETER.fullNodeAllowShieldedTransactionArgs = true;
929931
}
930932

933+
PARAMETER.rateLimiterGlobalQps =
934+
config.hasPath(Constant.RATE_LIMITER_GLOBAL_QPS) ? config
935+
.getInt(Constant.RATE_LIMITER_GLOBAL_QPS) : 50000;
936+
937+
PARAMETER.rateLimiterGlobalIpQps =
938+
config.hasPath(Constant.RATE_LIMITER_GLOBAL_IP_QPS) ? config
939+
.getInt(Constant.RATE_LIMITER_GLOBAL_IP_QPS) : 10000;
940+
931941
PARAMETER.rateLimiterInitialization =
932942
config.hasPath(Constant.RATE_LIMITER) ? getRateLimiterFromConfig(config)
933943
: new RateLimiterInitialization();
@@ -1480,6 +1490,8 @@ public static void logConfig() {
14801490
logger.info("Max connection with same IP: {}", parameter.getMaxConnectionsWithSameIp());
14811491
logger.info("Solidity threads: {}", parameter.getSolidityThreads());
14821492
logger.info("Trx reference block: {}", parameter.getTrxReferenceBlock());
1493+
logger.info("Rate limiter global qps: {}", parameter.getRateLimiterGlobalQps());
1494+
logger.info("Rate limiter global ip qps: {}", parameter.getRateLimiterGlobalIpQps());
14831495
logger.info("************************ Backup config ************************");
14841496
logger.info("Backup priority: {}", parameter.getBackupPriority());
14851497
logger.info("Backup listen port: {}", parameter.getBackupPort());

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,6 +30,8 @@ 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(), 50000);
34+
Assert.assertEquals(Args.getInstance().getRateLimiterGlobalIpQps(), 10000);
3335
Assert.assertEquals(Args.getInstance().p2pDisable, true);
3436
}
3537
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.tron.core.services.ratelimiter;
2+
3+
import java.lang.reflect.Field;
4+
import org.junit.Assert;
5+
import org.junit.Test;
6+
import org.tron.core.Constant;
7+
import org.tron.core.config.args.Args;
8+
9+
public class GlobalRateLimiterTest {
10+
11+
@Test
12+
public void testAcquire() throws Exception {
13+
String[] a = new String[0];
14+
Args.setParam(a, Constant.TESTNET_CONF);
15+
RuntimeData runtimeData = new RuntimeData(null);
16+
Field field = runtimeData.getClass().getDeclaredField("address");
17+
field.setAccessible(true);
18+
field.set(runtimeData, "127.0.0.1");
19+
Assert.assertEquals(runtimeData.getRemoteAddr(), "127.0.0.1");
20+
GlobalRateLimiter.acquire(runtimeData);
21+
}
22+
}

0 commit comments

Comments
 (0)