Skip to content

Commit 83bfdbc

Browse files
committed
feat: optimize long link
1 parent 0c7ed0b commit 83bfdbc

1 file changed

Lines changed: 20 additions & 1 deletion

File tree

  • trpc-proto/trpc-proto-http/src/main/java/com/tencent/trpc/proto/http/client

trpc-proto/trpc-proto-http/src/main/java/com/tencent/trpc/proto/http/client/HttpRpcClient.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.io.IOException;
2121
import java.util.concurrent.TimeUnit;
2222
import java.util.concurrent.atomic.AtomicInteger;
23+
import org.apache.http.config.SocketConfig;
2324
import org.apache.http.impl.client.CloseableHttpClient;
2425
import org.apache.http.impl.client.HttpClients;
2526
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
@@ -47,7 +48,12 @@
4748
* which beats most NAT idle timers (typical 5–15min);</li>
4849
* <li>{@code connectionTimeToLive}: hard ceiling — every connection is forcibly recycled
4950
* after {@value #CONNECTION_TTL_MINUTES}min regardless of activity, so backend IP rotation
50-
* (K8s pod drift, blue/green) is recovered from in bounded time.</li>
51+
* (K8s pod drift, blue/green) is recovered from in bounded time;</li>
52+
* <li>{@code SO_KEEPALIVE=true} on every pooled socket: a last-resort path so the OS
53+
* eventually surfaces dead peers in the worst-case "host pulled the plug / kernel
54+
* panic" black-hole scenario where no FIN/RST is ever sent. Linux defaults are
55+
* conservative (~2h11min) — the application-layer paths above will normally fire
56+
* long before this kicks in.</li>
5157
* </ul>
5258
*
5359
* <p><b>Health signalling to the cluster manager</b>. The cluster manager's periodic health
@@ -140,6 +146,19 @@ protected void doOpen() {
140146
// Re-validate idle pooled connections before reuse so we do not send a request through a
141147
// socket the server has already half-closed.
142148
cm.setValidateAfterInactivity(VALIDATE_AFTER_INACTIVITY_MS);
149+
// Enable TCP-level keep-alive (SO_KEEPALIVE) on every pooled socket. This gives the OS a
150+
// last-resort path for surfacing dead peers in the worst case where neither the
151+
// application-layer Keep-Alive timer (5min) nor connectionTimeToLive (10min) fires —
152+
// typically the "host pulled the plug / kernel panic" black-hole scenario where no FIN
153+
// or RST is ever sent. Linux defaults are conservative (~2h11min total: 7200s idle +
154+
// 9 × 75s probes) so this isn't a fast path, but it's a pure win — the alternative is
155+
// socket lingering until {@code tcp_retries2} (~15min) catches up. Operators who care
156+
// about faster recovery should tune sysctl {@code net.ipv4.tcp_keepalive_time/intvl/probes}
157+
// host-wide; Apache HttpClient 4.x's blocking IO does not expose per-socket
158+
// configuration of those values via SocketOptions, hence the OS default applies.
159+
cm.setDefaultSocketConfig(SocketConfig.custom()
160+
.setSoKeepAlive(true)
161+
.build());
143162
httpClient = HttpClients.custom()
144163
.setConnectionManager(cm)
145164
// Background eviction of stale & long-idle connections; keeps the pool tidy in

0 commit comments

Comments
 (0)