Testing Connections

在某些情况下,在第一次打开连接时发送某种健康检查请求可能会很有用。其中一种情况可能是使用 TCP Failover Client Connection Factory,以便如果所选服务器允许打开连接但报告其不健康,我们能够进行故障转移。

In some scenarios, it can be useful to send some kind of health-check request when a connection is first opened. One such scenario might be when using a TCP Failover Client Connection Factory so that we can fail over if the selected server allowed a connection to be opened but reports that it is not healthy.

为了支持此功能,请将 connectionTest 添加到客户端连接工厂。

In order to support this feature, add a connectionTest to the client connection factory.

/**
 * Set a {@link Predicate} that will be invoked to test a new connection; return true
 * to accept the connection, false the reject.
 * @param connectionTest the predicate.
 * @since 5.3
 */
public void setConnectionTest(@Nullable Predicate<TcpConnectionSupport> connectionTest) {
    this.connectionTest = connectionTest;
}

若要测试连接,请在测试中将一个临时侦听器附加到该连接。如果测试失败,则关闭连接并引发异常。与 TCP Failover Client Connection Factory配合使用时,这会触发尝试下一个服务器。

To test the connection, attach a temporary listener to the connection within the test. If the test fails, the connection is closed and an exception thrown. When used with the TCP Failover Client Connection Factory this triggers trying the next server.

只有来自服务器的第一个答复将发送到测试侦听器。

Only the first reply from the server will go to the test listener.

在以下示例中,如果我们在发送 PING 时服务器回复 PONG,则服务器被视为正常。

In the following example, the server is considered healthy if the server replies PONG when we send PING.

Message<String> ping = new GenericMessage<>("PING");
byte[] pong = "PONG".getBytes();
clientFactory.setConnectionTest(conn -> {
    CountDownLatch latch = new CountDownLatch(1);
    AtomicBoolean result = new AtomicBoolean();
    conn.registerTestListener(msg -> {
        if (Arrays.equals(pong, (byte[]) msg.getPayload())) {
            result.set(true);
        }
        latch.countDown();
        return false;
    });
    conn.send(ping);
    try {
        latch.await(10, TimeUnit.SECONDS);
    }
    catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
    return result.get();
});