Skip to content

Commit 0c7ed0b

Browse files
committed
feat: optimize long link test
1 parent aeb0cc1 commit 0c7ed0b

5 files changed

Lines changed: 59 additions & 14 deletions

File tree

trpc-core/src/main/java/com/tencent/trpc/core/common/Constants.java

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,27 @@ public class Constants {
111111
*/
112112
public static final String DEFAULT_CONNECT_TIMEOUT = "1000";
113113
/**
114-
* Default maximum number of connections 20480
115-
*/
116-
public static final String DEFAULT_MAX_CONNECTIONS = "20480";
114+
* Default maximum number of connections.
115+
*
116+
* <p>200 covers the great majority of internal RPC workloads while keeping the worst-case
117+
* resource footprint bounded:</p>
118+
* <ul>
119+
* <li>By Little's Law (concurrent in-flight = QPS × RT) 200 connections sustain
120+
* e.g. {@code QPS=20000 × RT=10ms} or {@code QPS=2000 × RT=100ms} on the HTTP/1.1
121+
* path where each connection serves one request at a time;</li>
122+
* <li>Far below the Linux default ephemeral-port range (~28k usable) so a connection
123+
* storm against an unreachable backend cannot exhaust the port pool;</li>
124+
* <li>Friendly to backend LBs whose per-source keep-alive limits are typically in the
125+
* low thousands.</li>
126+
* </ul>
127+
*
128+
* <p>Workloads that genuinely need more (high-fanout aggregation services, very high QPS
129+
* with long RT) should override per-{@code BackendConfig} via {@code maxConns}.</p>
130+
*
131+
* <p>Note: the trpc protocol path does not read this field — it sizes the connection pool
132+
* via {@code connsPerAddr} (default 4). Only the HTTP / HTTP/2 paths consume it.</p>
133+
*/
134+
public static final String DEFAULT_MAX_CONNECTIONS = "200";
117135
/**
118136
* Default maximum payload limit 10M
119137
*/
@@ -156,9 +174,36 @@ public class Constants {
156174
*/
157175
public static final String DEFAULT_SERVER_IDLE_TIMEOUT = "240000";
158176
/**
159-
* Default number of connections per address 2
160-
*/
161-
public static final String DEFAULT_CONNECTIONS_PERADDR = "2";
177+
* Default number of long-lived TCP connections to a single peer address.
178+
*
179+
* <p>Each business request is dispatched round-robin across these N channels
180+
* ({@code channelIdx.getAndIncrement() % N}); on a single channel Netty multiplexes many
181+
* in-flight RPCs via the protocol-level sequence id, so {@code N=1} would already saturate
182+
* a 1Gbps link in pure throughput. The default of <b>4</b> is chosen so that:</p>
183+
* <ul>
184+
* <li>Multiple Netty {@code EventLoop} threads run in parallel for a single peer —
185+
* no single EventLoop becomes a CPU bottleneck under high QPS;</li>
186+
* <li>Failure-domain isolation: when a channel is invalidated by READ_IDLE / RST /
187+
* half-close, the remaining 3 channels absorb traffic with minimal RT impact
188+
* (compared to {@code N=2} which would double the load on the surviving channel);</li>
189+
* <li>Resource cost stays bounded: 4 fd × ephemeral ports × ~16KB Netty buffer per
190+
* peer is negligible even with hundreds of peer addresses.</li>
191+
* </ul>
192+
*
193+
* <p>Tuning guidance (override per-{@code BackendConfig} via {@code connsPerAddr}):</p>
194+
* <ul>
195+
* <li>Low QPS / few peers: {@code 1~2} (saves resources);</li>
196+
* <li>High QPS / few peers: {@code 8~16} (more EventLoop parallelism);</li>
197+
* <li>Many peer IPs (hundreds+): leave at {@code 4}, the IP fan-out already
198+
* provides parallelism &amp; failure isolation;</li>
199+
* <li>Gateway / aggregation services: {@code 8}.</li>
200+
* </ul>
201+
*
202+
* <p><b>Compatibility note</b>: this default was {@code 2} in earlier versions. Upgrades
203+
* will see <b>per-peer inbound connections double</b> on the server side; review server
204+
* fd ulimits and LB per-source connection limits before rollout.</p>
205+
*/
206+
public static final String DEFAULT_CONNECTIONS_PERADDR = "4";
162207
public static final String DEFAULT_TRANSPORTER = TRANSPORTER_NETTY;
163208
public static final String DEFAULT_IO_MODE = IO_MODE_EPOLL;
164209
/**

trpc-core/src/test/java/com/tencent/trpc/core/common/config/BackendConfigTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public void testDefault() {
8484
assertEquals(16384, config.getSendBuffer());
8585
assertEquals(180000, config.getIdleTimeout().intValue());
8686
assertEquals(false, config.isLazyinit());
87-
assertEquals(2, config.getConnsPerAddr());
87+
assertEquals(4, config.getConnsPerAddr());
8888
assertEquals(1000, config.getConnTimeout());
8989
assertEquals(true, config.isIoThreadGroupShare());
9090
assertEquals(Constants.DEFAULT_IO_THREADS, config.getIoThreads());

trpc-core/src/test/java/com/tencent/trpc/core/common/config/ClientConfigTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public void testDefault() {
3838
assertEquals(16384, config.getSendBuffer());
3939
assertEquals(180000, config.getIdleTimeout().intValue());
4040
assertEquals(false, config.isLazyinit());
41-
assertEquals(2, config.getConnsPerAddr());
41+
assertEquals(4, config.getConnsPerAddr());
4242
assertEquals(1000, config.getConnTimeout());
4343
assertEquals(true, config.isIoThreadGroupShare());
4444
assertEquals(Constants.DEFAULT_IO_THREADS, config.getIoThreads());
@@ -141,7 +141,7 @@ public void testClientConfigEmptyBackendConfig() {
141141
assertEquals(16384, config.getSendBuffer());
142142
assertEquals(180000, config.getIdleTimeout().intValue());
143143
assertEquals(false, config.isLazyinit());
144-
assertEquals(2, config.getConnsPerAddr());
144+
assertEquals(4, config.getConnsPerAddr());
145145
assertEquals(1000, config.getConnTimeout());
146146
assertEquals(1000, config.getRequestTimeout());
147147
assertTrue(config.isSetDefault());
@@ -157,7 +157,7 @@ public void testClientConfigEmptyBackendConfig() {
157157
assertEquals(16384, backendConfig.getSendBuffer());
158158
assertEquals(180000, backendConfig.getIdleTimeout().intValue());
159159
assertEquals(false, backendConfig.isLazyinit());
160-
assertEquals(2, backendConfig.getConnsPerAddr());
160+
assertEquals(4, backendConfig.getConnsPerAddr());
161161
assertEquals(1000, backendConfig.getConnTimeout());
162162
assertEquals(1000, backendConfig.getRequestTimeout());
163163
assertTrue(backendConfig.isSetDefault());

trpc-core/src/test/java/com/tencent/trpc/core/common/config/ProtocolConfigTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,15 @@ public void testDefaultConfig() {
4242
assertEquals(true, config.isKeepAlive());
4343
assertEquals(Constants.DEFAULT_CHARSET, config.getCharset());
4444
assertEquals(Constants.DEFAULT_TRANSPORTER, config.getTransporter());
45-
assertEquals(20480, config.getMaxConns());
45+
assertEquals(200, config.getMaxConns());
4646
assertEquals(1024, config.getBacklog());
4747
assertEquals(Constants.DEFAULT_NETWORK_TYPE, config.getNetwork());
4848
assertEquals(16384, config.getReceiveBuffer());
4949
assertEquals(16384, config.getSendBuffer());
5050
assertEquals(10485760, config.getPayload());
5151
assertEquals(180000, config.getIdleTimeout().intValue());
5252
assertEquals(false, config.isLazyinit());
53-
assertEquals(2, config.getConnsPerAddr());
53+
assertEquals(4, config.getConnsPerAddr());
5454
assertEquals(1000, config.getConnTimeout());
5555
assertEquals(Constants.DEFAULT_IO_MODE, config.getIoMode());
5656
assertEquals(Boolean.TRUE, config.isIoThreadGroupShare());

trpc-core/src/test/java/com/tencent/trpc/core/common/config/ServiceConfigTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public void testDefaultConfig() {
6363
assertEquals(true, config.isKeepAlive());
6464
assertEquals(Constants.DEFAULT_CHARSET, config.getCharset());
6565
assertEquals(Constants.DEFAULT_TRANSPORTER, config.getTransporter());
66-
assertEquals(20480, config.getMaxConns());
66+
assertEquals(200, config.getMaxConns());
6767
assertEquals(1024, config.getBacklog());
6868
assertEquals(Constants.DEFAULT_NETWORK_TYPE, config.getNetwork());
6969
assertEquals(16384, config.getReceiveBuffer());
@@ -87,7 +87,7 @@ public void testDefaultConfig() {
8787
assertEquals(true, protocolConfig.isKeepAlive());
8888
assertEquals(Constants.DEFAULT_CHARSET, protocolConfig.getCharset());
8989
assertEquals(Constants.DEFAULT_TRANSPORTER, protocolConfig.getTransporter());
90-
assertEquals(20480, protocolConfig.getMaxConns());
90+
assertEquals(200, protocolConfig.getMaxConns());
9191
assertEquals(1024, protocolConfig.getBacklog());
9292
assertEquals(Constants.DEFAULT_NETWORK_TYPE, protocolConfig.getNetwork());
9393
assertEquals(16384, protocolConfig.getReceiveBuffer());

0 commit comments

Comments
 (0)