I am trying to build a Spring STOMP based application for exposing API's, we are using AWS ActiveMQ(AmazonMQ) as external broker for relaying STOMP messages.
We are observing an issue when we are testing our application under load with JMeter, a lot of Web Socket I/O Error are observed when clients try to connect to our STOMP server.
We are using below configuration
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
SslContext sslContext;
try {
sslContext =
SslContextBuilder.forClient()
.sslProvider(SslProvider.JDK)
.trustManager(
InsecureTrustManagerFactory.INSTANCE)
.build();
ReactorNettyTcpClient<byte[]> client =
new ReactorNettyTcpClient<>(
tcpClient ->
tcpClient.remoteAddress(socketAddressSupplier())
.secure(ssl -> ssl.sslContext(sslContext)),
new StompReactorNettyCodec());
registry
.enableStompBrokerRelay(stompBrokerConfigurationProperties.getRelay())
.setAutoStartup(true)
.setSystemLogin(stompBrokerConfigurationProperties.getLogin())
.setSystemPasscode(stompBrokerConfigurationProperties.getPassword())
.setClientLogin(stompProperties.getLogin())
.setClientPasscode(stompProperties.getPassword())
.setTcpClient(client);
registry.setApplicationDestinationPrefixes(stompProperties.getAppDestinationPrefix());
registry.setUserDestinationPrefix(stompProperties.getUserDestinationPrefix());
} catch (SSLException e) {
log.error("EXCEPTION_OCCURRED", e);
}
}
and configuration for client inbound and outbound channels
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.taskExecutor(threadPoolTaskExecutor("stompInbound-"));
}
@Override
public void configureClientOutboundChannel(ChannelRegistration registration) {
registration.taskExecutor(threadPoolTaskExecutor("stompOutbound-"));
}
public ThreadPoolTaskExecutor threadPoolTaskExecutor(String groupName) {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(poolConfigProperties.getInbound());
executor.setMaxPoolSize(poolConfigProperties.getInbound() + 20);
executor.setThreadGroupName(groupName);
executor.setThreadNamePrefix(groupName);
executor.initialize();
return executor;
}
We are using Spring Boot version 2.7.0
.
I am looking for suggestions/optimizations in my existing configuration so that our system can scale easily and support thousands of concurrent connections.
Thanks in advance..