You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
RabbitMQ Java client version 5.14.0 connection creation can hang forever on defective socket in the following scenario:
ConnectionFactory configured with useNio(), useSslProtocol(), and non-zero timeouts,
socket channel that does not write any data.
Environment:
Java: OpenJDK 11
OS: Linux CentOS 7 or Windows 10
RabbitMQ server: any
The defective socket channel occasionally happened in our production environment (possibly caused a by firewall or proxy).
I was able to reproduce it locally with a socket channel where the write operation always returns 0 bytes written or simply blocks:
intamqpPort = 5671// assumes RabbitMQ server running on localhost;intamqpProxyPort = 15671;
intconnectionTimeout = 5_000;
inthandshakeTimeout = 2_000;
// Simulate a connection via that doesn't send anything // using https://github.com/NetCrusherOrg/netcrusher-javaTransformFilterFactoryoutgoingTransformFilterFactory = clientAddress ->
buf -> {
try {
TimeUnit.SECONDS.sleep(20);
} catch (InterruptedExceptione) {}
};
try (varreactor = newNioReactor();
vartcpProxy = TcpCrusherBuilder.builder()
.withReactor(reactor)
.withBindAddress(newInetSocketAddress(amqpProxyPort))
.withConnectAddress("localhost", amqpPort)
.withOutgoingTransformFilterFactory(outgoingTransformFilterFactory)
.build()) {
tcpProxy.open();
ConnectionFactoryfactory = newConnectionFactory();
factory.setHost("localhost");
factory.setPort(amqpProxyPort);
factory.useSslProtocol();
factory.useNio();
factory.setConnectionTimeout(connectionTimeout);
factory.setHandshakeTimeout(handshakeTimeout);
ExecutorServiceexecutorService = Executors.newSingleThreadExecutor();
Future<Connection> futureConnection = executorService
.submit(() -> factory.newConnection());
futureConnection.get(15, TimeUnit.SECONDS);
// Expected: Timeout from RabbitMQ after 5+2 seconds// Actual: Timeout from Future after 15 seconds
}
On initial connection creation, the workaround is to have a separate thread that interrupts connection creation after a timeout.
But for auto-recovery there is no workaround.
The text was updated successfully, but these errors were encountered:
Thanks for the snippet to reproduce the issue. In this case the program blocks on ReadableByteChannel#read(ByteBuffer) during the TLS handshake. The TLS is done in blocking mode, so there's nothing we can do, as the read method does not honor the SO_TIMEOUT option.
A solution would be to refactor the TLS handshake in non-blocking mode, but this part is already a snake pit, so I'd prefer to avoid this. I'm investigating another solution that involves temporary channels for the handshake.
The handshake is in blocking mode and reading from a channel
in this mode does not honor so_timeout but using temporary
channels based on the socket input/output streams offers
a decent workaround for this stage.
Fixes#719
(cherry picked from commit 2751d46)
The handshake is in blocking mode and reading from a channel
in this mode does not honor so_timeout but using temporary
channels based on the socket input/output streams offers
a decent workaround for this stage.
Fixes#719
(cherry picked from commit 2751d46)
Conflicts:
pom.xml
RabbitMQ Java client version 5.14.0 connection creation can hang forever on defective socket in the following scenario:
useNio()
,useSslProtocol()
, and non-zero timeouts,Environment:
The defective socket channel occasionally happened in our production environment (possibly caused a by firewall or proxy).
I was able to reproduce it locally with a socket channel where the write operation always returns 0 bytes written or simply blocks:
On initial connection creation, the workaround is to have a separate thread that interrupts connection creation after a timeout.
But for auto-recovery there is no workaround.
The text was updated successfully, but these errors were encountered: