簡體   English   中英

Spring Integration DSL Tcp:如何防止過多記錄客戶端拒絕的連接

[英]Spring Integration DSL Tcp: How to prevent excessive logging of Connection refused on the client side

我使客戶端和服務器都能夠等待彼此連接,因此它們可以以任何順序獨立啟動。 此處描述的解決方案確實做到了這一點,即開箱即用,BUT客戶端始終使用java.net.ConnectException: Connection refused: connect將大量的堆棧跟蹤打印到我們的日志中java.net.ConnectException: Connection refused: connect ,然后是46行長的堆棧跟蹤,直到服務器啟動並連接發生。 這是不理想的。

我的問題是:如何應用我的自定義邏輯來微調要記錄的內容和時間。

到目前為止,我發現日志是由org.springframework.integration.handler.LoggingHandler打印的。 這充當一種錯誤通道,錯誤總是在此分發。 我找不到這套設備在哪里,因此可以用自己的實現替換它。 我設法配置了自己的默認錯誤通道,但是該通道是與預配置的LoggingHandler通道一起添加的,而不是替換它。

另一種方法是在發送第一條消息時設置更長的超時時間。 我也在為此而苦苦掙扎。 我試圖將它設置為outboundGateway ,作為.handle(Tcp.outboundGateway(clientConnectionFactory).remoteTimeout(1_000_000L))但是沒有任何效果。

好,解決了

問題實際上不是LoggingHandler或任何錯誤通道中的問題,但是如果服務器尚未立即准備就緒,則org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory.createSocket()會引發異常,然后TcpOutboundGateway將其記錄為老式的異常方式; 只有這樣,錯誤才會被分發到errorChannel ,在此可以對其作出反應; 並且默認的SI反應是再次打印它:)那是我最初沒有注意到的,該異常記錄了兩次。 可以通過使用自定義錯誤消息處理程序來防止第二個日志,但不能使用第一個。

TcpNetClientConnectionFactory.createSocket()調用默認Java的createSocket(),並且沒有設置超時的選項。 如果接收者尚未准備好,則方法調用幾乎立即失敗。 請參閱JDK的增強請求JDK-4414843

可能的解決方案是重寫TcpNetClientConnectionFactory.createSocket()以重復到服務器的連接嘗試,直到成功為止。

WaitingTcpNetClientConnectionFactory

public class WaitingTcpNetClientConnectionFactory extends TcpNetClientConnectionFactory {
    private final SocketConnectionListener socketConnectionListener;
    private final int waitBetweenAttemptsInMs;
    private final Logger log = LogManager.getLogger();

    public WaitingTcpNetClientConnectionFactory(
            String host, int port, 
            int waitBetweenAttemptsInMs, 
            SocketConnectionListener socketConnectionListener) {
        super(host, port);
        this.waitBetweenAttemptsInMs = waitBetweenAttemptsInMs;
        this.socketConnectionListener = socketConnectionListener;
    }

    @Override
    protected Socket createSocket(String host, int port) throws IOException {
        Socket socket = null;
        while (socket == null) {
            try {
                socket = super.createSocket(host, port);
                socketConnectionListener.onConnectionOpen();
            } catch (ConnectException ce) {
                socketConnectionListener.onConnectionFailure();
                log.warn("server " + host + ":" + port + " is not ready yet ..waiting");
                try {
                    Thread.sleep(waitBetweenAttemptsInMs);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    throw new IOException("interrupted while wating between connection attempts", ie);
                }
            }
        }
        return socket;
    }
}

作為額外的獎勵,我還設置了我自己的自定義接口SocketConnectionListener成功或失敗,因此應用程序的其他部分可以與其同步; 例如,等待流傳輸,直到服務器/對等節點准備就緒。

使用WaitingTcpNetClientConnectionFactory方式與TcpNetClientConnectionFactory相同。

HeartbeatClientConfig (僅相關位):

@Bean
public TcpNetClientConnectionFactory clientConnectionFactory(
        ConnectionStatus connectionStatus) {
    TcpNetClientConnectionFactory connectionFactory = new WaitingTcpNetClientConnectionFactory("localhost", 7777, 2000, connectionStatus);
    connectionFactory.setSerializer(new ByteArrayLengthHeaderSerializer());
    connectionFactory.setDeserializer(new ByteArrayLengthHeaderSerializer());
    return connectionFactory;
}

現在它只打印:

INFO [           main] o.b.e.d.s.h.client.HeartbeatClientRun    : Started HeartbeatClientRun in 1.042 seconds (JVM running for 1.44)
WARN [ask-scheduler-1] h.c.WaitingTcpNetClientConnectionFactory : server localhost:7777 is not ready yet ..waiting
WARN [ask-scheduler-1] h.c.WaitingTcpNetClientConnectionFactory : server localhost:7777 is not ready yet ..waiting
WARN [ask-scheduler-1] h.c.WaitingTcpNetClientConnectionFactory : server localhost:7777 is not ready yet ..waiting
WARN [ask-scheduler-1] h.c.WaitingTcpNetClientConnectionFactory : server localhost:7777 is not ready yet ..waiting

和往常一樣,完整的項目資源都可以在我的git上找到, 這是相關的commit

暫無
暫無

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

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