ActiveMQ Artemis migration to the pluggable quorum configuration - activemq-artemis

I have question about ActiveMQ Artemis cluster migration to the pluggable quorum configuration.
Currently we have a cluster in the test environment which has 6 servers (3 pairs of master and slave with classic replication), and I plan to migrate to the cluster with the pluggable quorum voting. The version of Artemis is 2.23.1.
I have configured another (pretest) cluster with 3 zookeeper nodes and 2 nodes of primary/backup Artemis. It seems to work well, but it is a pretest environment where we perform some experiments, and there are no clients and workload. So I have decided to reconfigure the test cluster to use pluggable quorum voting.
At first I thought that we can change role of each server from master to primary, and from slave to backup.
Previous configuration was - master:
<ha-policy>
<replication>
<master>
<check-for-live-server>true</check-for-live-server>
<vote-on-replication-failure>true</vote-on-replication-failure>
<quorum-size>2</quorum-size>
<group-name>group-for-each-pair</group-name>
</master>
</replication>
</ha-policy>
Slave:
<ha-policy>
<replication>
<slave>
<allow-failback>true</allow-failback>
<group-name>group-for-each-pair</group-name>
</slave>
</replication>
</ha-policy>
The group name is used for slave to determine to which master it has to connect to.
Unfortunately, this setting does not work in the primary and backup sections. I tried to configure it and get xsd validation error for broker.xml.
In the documentation there are some words about settings which are no longer needed in the pluggable quorum configuration:
There are some no longer needed classic replication configurations:
vote-on-replication-failure quorum-vote-wait vote-retries
vote-retries-wait check-for-live-server
But there is nothing about <group-name>. Maybe it is a documentation issue.
New configuration is - primary:
<ha-policy>
<replication>
<primary>
<manager>
<class-name>org.apache.activemq.artemis.quorum.zookeeper.CuratorDistributedPrimitiveManager</class-name>
<properties>
<property key="connect-string" value="zookeeper-amq1:2181,zookeeper-amq2:2181,zookeeper-amq3:2181"/>
</properties>
</manager>
</primary>
</replication>
</ha-policy>
Backup:
<ha-policy>
<replication>
<backup>
<manager>
<class-name>org.apache.activemq.artemis.quorum.zookeeper.CuratorDistributedPrimitiveManager</class-name>
<properties>
<property key="connect-string" value="zookeeper-amq1:2181,zookeeper-amq2:2181,zookeeper-amq3:2181"/>
</properties>
</manager>
<allow-failback>true</allow-failback>
</backup>
</replication>
</ha-policy>
When I tried start the cluster with these settings, I found that backup servers try to connect to any primary server, and some of them cannot start. And I have reverted back to the old configuration.
I read the documentation and found some settings which could help:
<coordination-id>. Used in multi-primary configuration and probably will not work in the section.
namespace in the Apache Curator settings. Maybe it can help to split servers to pairs where each backup will connect to it's primary in the same namespace. But it may be designed for another purpose (to have one zookeeper for the several separate clusters), and there could be some other problems.
Another option is to remove unnecessary 4 ActiveMQ Artemis servers and use only 1 pair of servers. It will require client reconfiguration, but clients will continue to work with only 2 remaining servers even if there are 6 servers remain in the connection string.
Is there a preferred way to migrate from classic replication to the pluggable quorum voting without changing cluster topology (6 servers)?
Any changes in this test environment (if succeeded) will be performed on the UAT and production clusters which have the same topology. So we would prefer a smooth migration if possible.

I recommend just using group-name as you were before. For example on the primary:
<ha-policy>
<replication>
<primary>
<manager>
<class-name>org.apache.activemq.artemis.quorum.zookeeper.CuratorDistributedPrimitiveManager</class-name>
<properties>
<property key="connect-string" value="zookeeper-amq1:2181,zookeeper-amq2:2181,zookeeper-amq3:2181"/>
</properties>
</manager>
<group-name>group-for-each-pair</group-name>
</primary>
</replication>
</ha-policy>
And on the backup:
<ha-policy>
<replication>
<backup>
<manager>
<class-name>org.apache.activemq.artemis.quorum.zookeeper.CuratorDistributedPrimitiveManager</class-name>
<properties>
<property key="connect-string" value="zookeeper-amq1:2181,zookeeper-amq2:2181,zookeeper-amq3:2181"/>
</properties>
</manager>
<group-name>group-for-each-pair</group-name>
<allow-failback>true</allow-failback>
</backup>
</replication>
</ha-policy>
That said, I strongly encourage you to execute performance tests with a single HA pair of brokers. A single broker can potentially handle millions of messages per second so it's likely that you don't need a cluster of 3 primary brokers. Also, if your applications are connected to the cluster nodes such that messages are produced on one node and consumed from another then having a cluster may actually reduce overall message throughput due to the extra "hops" a message has to take. Obviously this wouldn't be an issue for a single HA pair.
Finally, dropping from 6 brokers down to 2 would significantly reduce configuration and operational complexity, and it's likely to reduce infrastructure costs substantially as well. This is one of the main reasons we implemented pluggable quorum voting in the first place.

Related

Clustered ActiveMQ Artemis and producer/consumer load balancing configuration when broker fails

I have created an ActiveMQ Artemis cluster with two active brokers. I have created a custom load balancer to be able to initially distribute my queues in a static way according to my requirements and workload.
<connectors>
<connector name="broker1-connector">tcp://myhost1:61616</connector>
<connector name="broker2-connector">tcp://myhost2:62616</connector>
</connectors>
<cluster-connections>
<cluster-connection name="myhost1-cluster">
<connector-ref>broker1-connector</connector-ref>
<retry-interval>500</retry-interval>
<use-duplicate-detection>true</use-duplicate-detection>
<message-load-balancing>ON_DEMAND</message-load-balancing>
<max-hops>1</max-hops>
<static-connectors>
<connector-ref>broker2-connector</connector-ref>
</static-connectors>
</cluster-connection>
</cluster-connections>
My issue is that when broker1 is down then based on this topology I can recreate its queues on broker2 to avoid losing messages (by using connection string on producer (tcp://myhost1:61616,tcp://myhost2:62616)).
But then when broker1 becomes available again my producer is unaware of that and it stills uses the connection to broker2 (if that matters broker2 redistribution-delay is set to 0 and no consumers are registered). Is there a way or some configuration to resume my producer to write only to broker1.
This affects my consumers which are initially connected to broker1, and I am not sure if there is also some way/configuration to make them transparently bounce between these brokers or do I need to create two consumers (effectively one them will be idle) each one targeting the corresponding broker ?
There is no way for the broker to tell a client that it should connect to another node joining the cluster.
My recommendation would be to use HA with failback so that when one node fails then all the clients connected to that node failover to the backup and then when the original node comes back all the clients failback to the original node.
You may also find that you don't actually need a cluster of 2 brokers. Many users never perform the performance testing necessary to confirm that clustering is even necessary in the first place. They simply assume that a cluster is necessary. Such an assumption can needlessly complicate a platform's architecture and waste valuable resources. The performance of ActiveMQ Artemis is quite good. A single node can handle millions of messages per second in certain use-cases.

Connecting Artemis and Amazon MQ brokers

I am trying to connect an Apache Artemis broker with an Amazon MQ broker to create a hybrid architecture. I have tried connecting ActiveMQ with Amazon MQ, and I could achieve it by using "network connectors" in the broker.xml file and it worked fine.
For connecting Amazon MQ and Artemis brokers I have added below shown "bridge configuration" and the "connector" to the Artemis broker.xml file
<bridges>
<bridge name="my-bridge">
<queue-name>factory</queue-name>
<forwarding-address>machine</forwarding-address>
<filter string="name='rotor'"/>
<reconnect-attempts>-1</reconnect-attempts>
<user>admin</user>
<password>12345678</password>
<static-connectors>
<connector-ref>netty-ssl-connector</connector-ref>
</static-connectors>
</bridge>
</bridges>
<connectors>
<connector name="netty-ssl-connector">ssl://b-...c-1.mq.us-west-2.amazonaws.com:61617?sslEnabled=true;</connector>
</connectors>
I'm getting an exception: ssl schema not found.
So I'm trying to understand whether connecting the Artemis and AmazonMQ brokers is same as connecting Activemq and AmazonMQ brokers (i.e by changing the configuration in the broker.xml file)? If so, what are the changes I need to make to the above shown configuration?
ActiveMQ Classic (i.e. 5.x) and Amazon MQ use the OpenWire protocol to establish connections in a network of brokers. ActiveMQ Artemis supports clients using the OpenWire protocol. However, ActiveMQ Artemis uses its own "core" protocol for bridges and clustering. Therefore you won't be able to create a bridge from ActiveMQ Artemis to ActiveMQ Classic or Amazon MQ since those brokers don't understand the Artemis "core" protocol.
The ssl schema is used by OpenWire clients, not "core" clients. That is why you can't create an Artemis bridge using it.
If you want to integrate Artemis and Amazon MQ I'd recommend something like Camel or even possibly the JMS bridge that ships with Artemis. You can see examples of both in this example which ships with Artemis.

Does ActiveMQ Artemis support master to master failover?

I have two ActiveMQ Artemis servers (server1 and server2). Both are the master and there is no slave in this case. Does Artemis support master to master failover? If yes, can any one provide the broker configuration. Currently I have defined following configuration in both server's broker.xml file.
<ha-policy>
<shared-store>
<master>
<failover-on-shutdown>true</failover-on-shutdown>
</master>
</shared-store>
</ha-policy>
Also, if possible can you please provide the sample client code for test the master to master failover scenario?
Failover support in ActiveMQ Artemis is provided by a master/slave pair as that is the only configuration where two brokers have the same journal data (either via shared-storage or replication). Failover between one master and another master is not supported.

Filtering in ActiveMQ Artemis. Reload of config in a cluster

A question about Filtering in ActiveMQ Artemis.
If I have a queue named MyQueue.IN and a filter only accepting a certain JMS Headers. Let's say ORDER.
In Broker.xml under the tag
<core>
<configuration-file-refresh-period>5000</configuration-file-refresh-period>
<queues>
<queue name="MyQueue.IN">
<address>MyQueue.IN</address>
<filter string="TOSTATUS='ORDER'"/>
<durable>true</durable>
</queue>
</queues>
</core>
As I read the manual, changing the Broker.xml it should now relaod config in Broker.xml every 5 seconds.
But when I change the filter to
<filter string="TOSTATUS='ORDERPICKUP'"/>
The config is not changed in ActiveMQ Artemis.
Not even if I restart the node.
It is in a cluster but I have changed Broker.xml on both sides.
Any ideas on how to change a filter on a queue? Preferably by changing the Broker.xml
/Zeddy
You are seeing the expected behavior. Although this behavior may not be intuitive or particularly user friendly it is meant to protect data integrity. Queues are immutable so once they are created they can't be changed. Therefore, to "change" a queue it has to be deleted and re-created. Of course deleting a queue means losing all the messages in the queue which is potentially catastrophic. In general, there are 2 ways to delete the queue and have it re-created:
Set <config-delete-queues>FORCE</config-delete-queues> in a matching <address-setting>. However, there is currently a problem with this approach which will be resolved via ARTEMIS-2076.
Delete the queue via management while the broker is running. This can be done via the JMX (e.g. using JConsole), the web console, the Artemis CLI, etc. Once the broker is stopped, update the XML, and then restart the broker.

Understanding Connectors ActiveMQ Artemis

I am new in ActiveMQ Artemis
I have read doc and found connectors are used by a client to define how it connects to a server.
I have a broker.xml file which have following peace of code
<connectors>
<connector name="netty-connector">tcp://0.0.0.0:61616</connector>
<!-- connector to the server1 -->
<connector name="server1-connector">tcp://0.0.0.0:9616</connector>
</connectors>
<!-- Acceptors -->
<acceptors>
<acceptor name="netty-acceptor">tcp://0.0.0.0:61616</acceptor>
</acceptors>
so here acceptor is saying,Hey you can connect with me on port 61617, I am listening on it(which is making sense for me)
but what about role of connector in this broker.xml.
Connector is targeting same port(tcp://0.0.0.0:61616) as in acceptor,
I want to understand it what is it port means which is mentioned in Connector, can some please explain it.
Did you happen to read the documentation on this subject? There is a section titled "Understanding Connectors" which should answer most, if not all, of your questions. I'll quote the most salient parts:
Whereas acceptors are used on the server to define how we accept connections, connectors are used to define how to connect to a server.
A connector is used when the server acts as a client itself, e.g.:
When one server is bridged to another
When a server takes part in a cluster
In these cases the server needs to know how to connect to other servers. That's defined by connectors.