Load Balancing ActimeMQ Artemis in JBoss EAP 7.2.0 - spring-boot

We are developing an application using Spring Boot and Apache Camel that is reading a message from ActiveMQ Artemis, doing some transformation, and sending it to ActiveMQ Artemis. Our application is deployed as war file in on-premise JBoss EAP 7.2.0. Both the source and target applications are remote to our application and they are also deployed on JBoss EAP 7.2.0. The remote queues to which Camel is connecting are ActiveMQ Artemis which were created in JBoss and connecting using http-remoting protocol. These setup was working when there were only one node of each of the applications.
Now we are making the source and target applications 3 nodes each (i.e. they will be deployed in multiple JBoss servers). For accessing the front-end of the source and target applications we are configuring and accessing them through a load balancer.
Can we configure the load balancer to access the source and target brokers from the Camel layer? There will be 3 source and 3 target brokers. Or is clustering the brokers the only option in this case?
We are thinking of load balancing between the queues and not clustering. Suppose we have three queues q1, q2, and q3 with corresponding brokers b1, b2, and b3. I will configure the load balancer url in the Camel layer like http-remoting://<load-balancer-url>:<port> (much like we do while load balancing HTTP API requests). Any message coming in will hit the load balancer, and the load balancer will decide which queue to route the message to.

JMS connections are stateful. When a client creates a connection there is no indication of the queues to which it will send messages. The load-balancer will have to direct that client's connection to either b1, b2, or b3 and it will have no way to determine where it should go. A load-balancer working with messaging will almost certainly only be able to balance connections, not messages. It sounds like you want load-balancing at the message level instead. Perhaps you should look into something like Qpid Dispatch Router.
Messaging doesn't use HTTP so using an HTTP load balancer like you do with your HTTP API(s) won't work. It's easy for a load-balancer to inspect HTTP headers and route requests, especially since HTTP is stateless. However, messaging connections are stateful and the protocols are typically quite a bit more complex than HTTP. I don't know of any load-balancers that will work the way you are wanting for messaging.

You need your client not to use the topology, you can do this by using "setUseTopologyForLoadBalancing" on your AMQConnectionFactory. If you get the connection factory from EAP I think this is configurable on the connection factory since EAP 7.3.

Related

Avoid multiple listens to ActiveMQ topic with Spring Boot microservice instances

We have configured our ActiveMQ message broker as a Spring Boot project and there's another Spring Boot application (let's call it service-A) that has a listener configured to listen to some topics using #JmsListener annotation. It's a Spring Cloud microservice appilcation.
The problem:
It is possible that service-A can have multiple instances running.
If we have 2 instances running, then any message coming on topic gets listened to twice.
How can we avoid every instance listening to the topic?
We want to make sure that the topic is listened to only once no matte the number of service-A instances.
Is it possible to run the microservice in a cluster mode or something similar? I also checked out ActiveMQ virtual destinations but not too sure if that's the solution to the problem.
We have also thought of an approach where we can decide who's the leader node from the multiple instances, but that's the last resort and we are looking for a cleaner approach.
Any useful pointers, references are welcome.
What you really want is a shared topic subscription which was added in JMS 2. Unfortunately ActiveMQ 5.x doesn't support JMS 2. However, ActiveMQ Artemis does.
ActiveMQ Artemis is the next generation broker from ActiveMQ. It supports most of the same features as ActiveMQ 5.x (including full support for OpenWire clients) as well as many other features that 5.x doesn't support (e.g. JMS 2, shared-nothing high-availability using replication, last-value queues, ring queues, metrics plugins for integration with tools like Prometheus, duplicate message detection, etc.). Furthermore, ActiveMQ Artemis is built on a high-performance, non-blocking core which means scalability is much better as well.

Difference between Kafka and load balancer (Ribbon)

I am new to Kafka.
I have existing microservice with spring-boot, ribbon, eruka, and zuul.
If I use Kafka as the messaging platform between each microservice call, does kafka provide load balancer for microservice and I can get rid of ribbon ?
Please give me some suggestions.
Thanks
Kafka stores data in a distributed log and provides external clients for building a streaming platform. It is not a load balancer; but data is partitioned amongst servers so load is distributed as part of its custom TCP protocol.
Ribbon is a stateless service for spreading load over other services. I haven't used it, but it does not have an asynchronous, client, push-pull model to anything
You could use them together... A Kafka consumer would start an HTTP / RPC call to a Ribbon server

Wildfly JMS server master and slave behavior

I'm looking for the easiest way to build a Wildfly cluster with JMS load balancing for a development platform. Messages will be produced by the Wildfly servers themselves.
I wonder how works the ActiveMQ Artemis JMS server embedded in Wildfly in a cluster deployment. I see on this site that a Wildfly node can declare its JMS server as master or slave.
I also read here that a MDB can use an "in-vm-connector" connector.
I'm not sure that I understand how a JMS cluster works with a master and a slave JMS server with "in-vm-connector". Will the MDB instances in the Wildfly node with the slave JMS server receive messages? Will the JMS cluster provide load balancing or will there be only one active JMS server at the same time?
In ActiveMQ Artemis (i.e. the JMS broker embedded into WildFly) clustering (which provides things like message load balancing) and high-availability (which provides redundancy for the integrity of the message data) are separate concepts. The master/slave configuration you mentioned is for high-availability. This configuration doesn't provide message load balancing since only one of the brokers is alive at any given point in time.
If you want configure a master/slave pair it's recommended that you separate those servers from the servers that actually process the messages since it doesn't make sense to have MDBs running on a server which doesn't have a live broker (i.e. a slave) since they won't receive any messages.

How to bridge between IBM MQSeries and ActiveMQ Artemis 7.x?

Has anyone succeeded in creating a bridge between IBM MQSeries (MQS) and ActiveMQ Artemis 7.x (AMQ 7) so that the later can send messages to and receive from the first? Currently I have no problem bridging between MQS 7.5 and AMQ 6.3 by deploying a camel route and MQS libraries on the broker itself. However, the same way doesn't work anymore as each route deployment requires a broker reconfiguration and restart.
Thanks in advance for any feedback.
A few examples ship with ActiveMQ Artemis which might be helpful:
The "inter-broker-bridge" example in the examples/features/sub-modules/ directory. This example demonstrates how to deploy an instance of org.apache.activemq.artemis.jms.bridge.impl.JMSBridgeImpl to the broker using Spring in a web application.
The "camel" example in the examples/features/standard/ directory. This example demonstrates how to deploy a Camel route to the broker using Spring in a web application.
I can't speak to whether or not either of these can be updated at runtime as I've not actually attempted that. Both of these options should be able to move messages in either direction (i.e. from Artemis to MQS or from MQS to Artemis).
Another option would simply be to run Camel standalone and deploy your routes there. This would give you more flexibility as it would allow you to specifically choose the hardware where the routes run as well as how many resources the Camel JVM consumes. Running Camel routes directly on the broker, while convenient, isn't a great fit because the broker is a broker and not an application server.
To be clear, ActiveMQ Artemis and IBM MQSeries are not directly compatible with each other and are not expected to be. This true for most (if not all) JMS broker implementations. The role of components like the ActiveMQ Artemis JMS bridge and integration platforms like Camel are to solve the compatibility problem by using a common API to speak to both brokers - JMS in this case. Any broker which implements JMS can be integrated using these methods.

Spring 4 websocket + stomp + rabbitmq and clustering

I am going through Spring 4 websocket + stomp + rabbitmq(RabbitMQ-Web-Stomp plugin) architecture and I have a question about clustering. As per my understanding here Spring MVC act as a gateway for STOMP requests. If we cluster the application instance with spring web socket configuration will it create any confusion? For an example will it open multiple listeners and how will in such a case this architecture behave?
In this scenario, you would need to use load balancing and a message broker. I used HAProxy to load balance 4 Spring MVC instances (websocket) running on 4 tomcat servers. Also configure rabbit mq as a broker. From client code connect to the single HAProxy url.
If you don't use the message broker, then the websocket client subscriptions will be maintained in the app/ web server's (tomcat) JVM and in case one instance goes down, all the subscriptions on that would be lost.

Resources