簡體   English   中英

Spring 集成 | TCP 空閑等待 350 秒后連接斷開

[英]Spring Integration | TCP Connections dropping after idle wait of 350 seconds

我們有一個在 aws 上運行的 java spring 集成應用程序(Kubernetes 集群中的多個 pod)。 我們使用 TCP 出站網關與第三方系統通信,並使用 CachingClientConnectionFactory 工廠緩存這些連接。 在出廠時,我們將 sokeepalive 設置為 true,但是我們仍然看到 350 秒后連接斷開。 在 350 秒的空閑等待時間之前,我們是否需要配置中的任何其他內容來保持對服務器的 ping 操作? AWS 在這里談論 350 秒的限制 - https://docs.aws.amazon.com/vpc/latest/userguide/nat-gateway-troubleshooting.html#nat-gateway-troubleshooting-timeout

我們的連接工廠和網關的配置如下

@Bean
    public AbstractClientConnectionFactory primeClientConnectionFactory() {
        TcpNetClientConnectionFactory tcpNetClientConnectionFactory = new TcpNetClientConnectionFactory(host, port);

        tcpNetClientConnectionFactory.setDeserializer(new PrimeCustomStxHeaderLengthSerializer());
        tcpNetClientConnectionFactory.setSerializer(new PrimeCustomStxHeaderLengthSerializer());
        tcpNetClientConnectionFactory.setSingleUse(false);
        tcpNetClientConnectionFactory.setSoKeepAlive(true);

        return tcpNetClientConnectionFactory;
    }

    @Bean
    public AbstractClientConnectionFactory primeTcpCachedClientConnectionFactory() {
        CachingClientConnectionFactory cachingConnFactory = new CachingClientConnectionFactory(primeClientConnectionFactory(), connectionPoolSize);
        //cachingConnFactory.setSingleUse(false);
        cachingConnFactory.setLeaveOpen(true);
        cachingConnFactory.setSoKeepAlive(true);
        return cachingConnFactory;
    }

    @Bean
    public MessageChannel primeOutboundChannel() {
        return new DirectChannel();
    }

    @Bean
    public RequestHandlerRetryAdvice retryAdvice() {
        RequestHandlerRetryAdvice retryAdvice = new RequestHandlerRetryAdvice();
        RetryTemplate retryTemplate = new RetryTemplate();
        FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
        fixedBackOffPolicy.setBackOffPeriod(500);
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        retryPolicy.setMaxAttempts(3);
        retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
        retryTemplate.setRetryPolicy(retryPolicy);
        retryAdvice.setRetryTemplate(retryTemplate);
        return retryAdvice;
    }

    @Bean
    @ServiceActivator(inputChannel = "primeOutboundChannel")
    public MessageHandler primeOutbound(AbstractClientConnectionFactory primeTcpCachedClientConnectionFactory) {
        TcpOutboundGateway tcpOutboundGateway = new TcpOutboundGateway();
        List<Advice> list = new ArrayList<>();
        list.add(retryAdvice());
        tcpOutboundGateway.setAdviceChain(list);

        tcpOutboundGateway.setRemoteTimeout(timeOut);
        tcpOutboundGateway.setRequestTimeout(timeOut);
        tcpOutboundGateway.setSendTimeout(timeOut);
        tcpOutboundGateway.setConnectionFactory(primeTcpCachedClientConnectionFactory);
        return tcpOutboundGateway;
    }

}

有關 Keep Alive 的更多信息,請參閱此 SO 線程: TCP 套接字連接是否具有“保持活動狀態”? .

根據當前 Java 凈 API 我們得到這個 class:

/**
 * Defines extended socket options, beyond those defined in
 * {@link java.net.StandardSocketOptions}. These options may be platform
 * specific.
 *
 * @since 1.8
 */
public final class ExtendedSocketOptions {

它提供了這個常數:

/**
 * Keep-Alive idle time.
 *
 * <p>
 * The value of this socket option is an {@code Integer} that is the number
 * of seconds of idle time before keep-alive initiates a probe. The socket
 * option is specific to stream-oriented sockets using the TCP/IP protocol.
 * The exact semantics of this socket option are system dependent.
 *
 * <p>
 * When the {@link java.net.StandardSocketOptions#SO_KEEPALIVE
 * SO_KEEPALIVE} option is enabled, TCP probes a connection that has been
 * idle for some amount of time. The default value for this idle period is
 * system dependent, but is typically 2 hours. The {@code TCP_KEEPIDLE}
 * option can be used to affect this value for a given socket.
 *
 * @since 11
 */
public static final SocketOption<Integer> TCP_KEEPIDLE
        = new ExtSocketOption<Integer>("TCP_KEEPIDLE", Integer.class);

所以,我們在TcpNetClientConnectionFactory上需要的是:

public void setTcpSocketSupport(TcpSocketSupport tcpSocketSupport) {

實現那個void postProcessSocket(Socket socket); 能夠做到這一點:

            try {
                socket.setOption(ExtendedSocketOptions.TCP_KEEPIDLE, 349);
            }
            catch (IOException ex) {
                throw new UncheckedIOException(ex);
            }

根據您與我們共享的 AWS 文檔。

另請參閱 Spring 集成文檔中的一些信息: https://docs.spring.io/spring-integration/docs/current/socketsupport/sthtml/ip.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM