Spring websocket/broker fail over - spring

I have the following design:
Machine1
WebsocketApp
ActiveMQ broker
Machine2
WebsocketApp
ActiveMQ broker
Machine3
WebsocketApp
ActiveMQ broker
Machine4
WebsocketApp
ActiveMQ broker
The clients will use STOMP over WebSockets through an F5 load-balancer to connect to the ActiveMQ brokers. They can land on any machines based on the load factor.
For fail over scenarios how do we share the web socket sessions between ActiveMQ. Otherwise if the broker goes down all the sessions that it is holding will go down.

STOMP is a very simple protocol. It has no support for fail-over.
If the broker to which a STOMP client is connected goes down in your environment then that client's connection will go down and all the messages on that broker will be unavailable until the broker comes back up. The client will need to reconnect to another broker via the F5 URL.
STOMP connections are not like HTTP. They are stateful. Client "session" data is not shared among brokers. If a client's broker goes down then it cannot simply carry on as if nothing happened like is often possible for HTTP use-cases.

Related

How do I distribute JMS Listener Connections to ActiveMQ Network of Brokers using Spring Boot JMS?

Our JMS Listener application connects to an ActiveMQ network of brokers through a load balancer, which we are told distributes connections amongst brokers in a round-robin fashion. Our spring boot application is creating a connection via the load balancer, which in turn feeds the connection to one of the brokers amongst the network of brokers. If a message is published to the brokers then it would be a lot quicker if the message was on the broker that the JMS listener connection lived on. However, the likelihood of that occurring is slim unless we can distribute the connections across the brokers.
I've tried increasing the concurrency in the DefaultJmsListenerContainerFactory, but that didn't do the trick. I was thinking about somehow extending the AbstractJmsListenerContainerFactory, and somehow create a Map of DefaultMessageListenerContainer instances but it looks like the createListenerContainer will only return an instance of whatever is parameterized in the AbstractJmsListenerContainerFactory and we cannot parameterize it with an instance of Map.
We are using Spring Boot 1.5.14.RELEASE.
== UPDATE ==
I've been playing around with the classes above, and it seems like it is inherent in Spring JMS that a Jms Listener be associated with a Single Message Listener Container, which in turn is associated with a single (potentially shared) connection.
For any folks that have JMS Application Listeners that are connecting to a load balanced network of brokers, are you creating a single connection that is connecting to a single broker, and if so, do you experience significant performance degradation as a result of the network of brokers having to move any inbound messages to a broker with consumers?

Kafka consumer with TLS. Performance issue

In my application I have kafka configured to work with TLS, so I have few consumers which each time polling the new messages from the broker.
Problem is that if I have 5 consumers and each is performing poll for each 100 ms, I have a tones of SSLHandshakes.
I aware about "session resumption" that I used to use in web services. My question:
Is there any possibility to say to the kafka consumer that it doesn't need to perform handshake each time, and use symmetric key that was created during the first handshake?
TLS Handshake is only performed when creating the connection. See https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_handshake
Kafka Consumers keep the connection alive between polls, so each Consumer only performs a TLS Handshake once, to each broker it's using, at startup.

Apache ActiveMQ Artemis Netty Client send Message trough HTTP Proxy

I'm behind a corporate HTTP proxy and want to send and receive messages to/from a ActiveMQ Artemis broker in the cloud.
On the broker Netty HTTP is activated and I'm able to send and receive messages using the Netty based ActiveMQ Artemis client on a computer without HTTP proxy.
I know that Netty HTTP client can be configured to use a HttpProxyHandler but I didn't find a way to configure this with the ActiveMQ Artemis client.
Any help is highly appreciated.

How does Spring mange websocket connections to RabbitMQ?

I have a game server that uses websocket for real time multiplayers. It is a Spring 4 application and I use RabbitMQ as my broker. This is my configuration:
<websocket:message-broker application-destination-prefix="/app">
<websocket:stomp-endpoint path="/portfolio">
<websocket:sockjs/>
</websocket:stomp-endpoint>
<websocket:simple-broker prefix="/queue, /topic"/>
</websocket:message-broker>
From a very small test with 4 clients I saw 4 connections open on Rabbit.
Does each client that connects to my server using websocket eventually open a new connection to the broker (RabbitMQ)? Can this be configured?
Yes, each websocket client gets its own TCP connection to the broker. The documentation has a section for connections to the broker (emphasis mine):
A STOMP broker relay maintains a single "system" TCP connection to the broker. This connection is used for messages originating from the server-side application only, not for receiving messages. [...]
The STOMP broker relay also creates a separate TCP connection for every connected WebSocket client. [ ... ]
If this can be configured or not I don't know, I'm not all that familiar with this part of Spring, but I assume it should be; Spring is open to extension. My suggestion is to post an issue on the spring-websocket-portfolio project and ask for specifics.
EDIT : OP opened the following issue on the spring-websocket-portfolio project.

How does a JMS consumer work on a broker CLUSTER of Oracle Message Queue?

We have an application running in a GlassFish 3.1.2.2 cluster (two instances) that writes its results to "the_output_queue".
GlassFish sets up Message Queue as an embedded broker cluster, which in turn has also two message broker instances corresponding directly to the two GlassFish instances.
Now I would like to consume results from the_output_queue with an external JMS client (think Android app).
I assumed that a broker cluster can somehow be accessed transparently by a JMS client, but I cannot get this to work. I only succeed in connecting a JMS client to one individual broker.
If I have one JMS client running, connected to one broker I get only half of the messages. The physical queue (the_output_queue) defined in the GlassFish Administration Console exists in both brokers and the messages get evenly distributed thanks to load balancing.
This text from the Oracle manuals sounds to me like every message should be available in all broker instances of the cluster, i.e. if only a single JMS consumer is running it should receive all messages irrespective of the broker instance it is connected to.
"The home broker is responsible for routing and delivering the messages to all consumers of the destination, whether these consumers are local (connected to the home broker) or remote (connected to other brokers in the cluster)."
Have I misunderstood this completely?
Can a JMS client access a Oracle Message Queue broker cluster transparently?
How would the connection string look?
Is there some "global cluster target" (instead of an individual broker) to which the JMS client can connect? Where could I find the connection details for the cluster?
Is there something special in the GlassFish setup I have to verify? The settings currently are (default setup created by jelastic.com, looks good to me):
JMS Availability:
JMS Service Type: Embedded
JMS Cluster Type: Conventional
JMS Configuration Store Type: Master Broker
JMS Message Store Type: File
GMS is enabled
Answer to the main question: Yes, a JMS client can connect to any instance of a cluster and GlassFish will replicate the messages. I have tested it on my PC.
The problem in Jelastic is discussed in this posting.

Resources