1 Overview
For the scale-out and high availability of the system required for massive messages, ACTIVEMQ provides a clustering feature for network connectivity patterns.
Simply put, it is by connecting a number of different broker instances together as a whole to provide services to the outside, thereby improving the overall external messaging capabilities.
Between broker instances that are connected in this way, the queue and consumer list can be shared to achieve the purpose of the distributed queue.
< c32>2 Custom installation 2.1 Deployment Structure
machine1:192.168.1.106
machine2:192.168.1.107
2.2 Installation Steps
The installation steps are as follows:
1, decompression;
TAR-ZXVF apache-activemq-5.9.0-bin.tar.gz
2, related configuration, edit/conf/activemq.xml configuration file,
(implemented using the Staticbroker-cluster configuration method ):
can refer to the official website:
http://activemq.apache.org/networks-of-brokers.html
1) Set the data reflow configuration:
New under <policyEntries> node:
<!--property Enableaudit=false to prevent messages from being treated as duplicates after reflow and not forwarded--
<policyentryqueue= ">" producerflowcontrol= " False "memorylimit=" 10MB "enableaudit=" false ">
<!--property Replaywhennoconsumers=true, guaranteed after the node is disconnected and restarted, And consumers is connected to another node, the message automatically flows back to the original node-
<networkBridgeFilterFactory>
< Conditionalnetworkbridgefilterfactoryreplaywhennoconsumers= "true"/>
</networkBridgeFilterFactory>
</policyEntry>
2) Set a reference to Machine2 on the Machine1
Configure multiple comma-separated host
<networkconnectoruri= "Static: (tcp://host1:61616,tcp://host2:61616)" duplex= "true"/>
or
<networkConnectors>
<networkconnectoruri= "static: (tcp://192.168.1.107:61617)" duplex= "true"/>
</networkConnectors>
<transportConnectors>
<!--dosprotection, limit concurrent connections to $ and frame size to 100MB--
<transportconnectorname= "Openwire" uri= "tcp://0.0.0.0:61616?maximumconnections=1000& wireformat.maxframesize=104857600 "/>
.....
</transportConnectors>
3) Set a reference to Machine1 on the Machine2
<networkConnectors>
<networkconnectoruri= "static: (tcp://192.168.1.106:61616)" duplex= "true"/>
</networkConnectors>
<transportConnectors>
<!--DOS Protection, limitconcurrent connections to $ and frame size to 100MB
<transportconnectorname= "Openwire" uri= "tcp://0.0.0.0:61617?maximumconnections=1000&wireformat.m axframesize=104857600 "/>
... ..
</transportConnectors>
2. Start:
Execute/bin directory under ACTIVEMQ
Start the ACTIVEMQ on Machine1 and Machine2 respectively
./activemq Start &
3. View the log after startup:
The following log shows that the cluster cluster are interconnected, indicating that the cluster Brokercluster cluster is configured successfully.
2.3 Property Description 2.3.1 Networkconnector Configuration Parameters
<networkConnectors>
<networkconnectoruri= "static: (tcp://host1:61616,tcp://host2:61616,tcp://.)" />
</networkConnectors>
Several properties of the URI:
Properties |
Default Value |
Description |
Initialreconnectdelay |
1000 |
Time (MS) to wait before re-connecting (if Useexponentialbackoff is false) |
Maxreconnectdelay |
30000 |
Maximum time to wait before re-connect (MS) |
Useexponentialbackoff |
True |
Whether to increase the wait time for each re-connection failure |
Backoffmultiplier |
2 |
Increase the factor of the wait time |
Networkconnector Parameter Properties
Properties |
Default Value |
Description |
Name |
Bridge |
Name |
Dynamiconly |
False |
If true, the persistent subscription is activated when the corresponding network durable subscription is created. The default is activate at startup. |
Decreasenetworkconsumerpriority |
False |
If true, the network's consumer priority is reduced to-5. If False, the default is 0 as the local consumer. |
Networkttl |
1 |
Number of brokers passed on the network for messages and subscriptions |
Conduitsubscriptions |
True |
Whether multiple Internet consumers are treated as a consumer. |
Excludeddestinations |
Empty |
Destination that are not forwarded over the network |
Dynamicallyincludeddestinations |
Empty |
Destinations forwarded over the network, note that empty lists are forwarded on behalf of all. |
Staticallyincludeddestinations |
Empty |
Matched will be forwarded over the network-even if there is no corresponding consumer |
Duplex |
False |
If true, both consumption and production messages to the network broker can be |
Prefetchsize |
1000 |
Set the prefetch size parameter for the network consumer. must be greater than 0 because the network consumer cannot poll the message itself. |
Suppressduplicatequeuesubscriptions |
False |
(starting with version 5.3) If true, duplicate subscription relationships are blocked as a result. |
Bridgetempdestinations |
True |
Whether to broadcast advisory messages to create a temporary destination. |
Alwayssyncsend |
False |
(starting with version 5.6) If true, non-persisted messages will also be sent to the remote broker in request/reply mode instead of OneWay. |
Staticbridge |
False |
(starting with version 5.6) If true, only the destination configured in Staticallyincludeddestinations can be processed. |
2.4 Scene Description
A very interesting scenario is that Broker1 and Broker2 are connected by Networkconnector. Some of the consumers connect to Broker1, consuming broker2 messages. Messages are first consumed by broker1 from the Broker2, and then forwarded to these consumers. Unfortunately, when the message was forwarded, Broker1 restarted, and these consumers found that the Broker1 connection failed and was connected to Broker2 via failover. But a part of the news that they haven't consumed has been distributed to broker1 by Broker2. These messages are as if they were gone, unless consumers reconnect to broker1 to spend. How to do it.
The idea is to add the option Replaywhennoconsumers from version 5.6 Destinationpolicy. This option causes the message to be forwarded on the broker1, but when there is no consumer, the message is returned to its original broker. At the same time, set the EnableAudit to false, in order to prevent the message reflow after being treated as a duplicate message and not be distributed.
3 Cluster principle
The implementation principle of Networkconnector is based on the ACTIVEMQ announcement message (advisorymessage) mechanism (see here). What happens when Broker2 points to broker1 through the networkconnector and duplex way.
Assuming the Broker1 has started, Broker2 starts.
1. Broker2 start your own connector first
2. Then use the connector of a VM, create a connection, and connect yourself as a client to Broker1.
3. By subscribing to the Advisorymessage, get the mutual consumer and the corresponding queue list.
At this point, the two sides establish relations.
4 Cluster Scenario testing 4.1 Cluster Testing
1. Send queue data using Java client,
1) Connect 61616 on the producer to send the data; |
2) Connect 61617 on the consumer to receive data; |
Product Code:
public class Producer {private static final String Broker_url = "tcp://192.168.1.106:61616";
private static final Boolean non_transacted = false;
private static final int num_messages_to_send = 100;
Private static final long DELAY = 100;
public static void Main (string[] args) {String url = broker_url;
if (Args.length > 0) {url = Args[0].trim ();
} activemqconnectionfactoryconnectionfactory = new Activemqconnectionfactory ("admin", "admin", url);
Connection Connection = null;
try {connection = connectionfactory.createconnection ();
Connection.start ();
Session session =connection.createsession (non_transacted, Session.auto_acknowledge);
Destination Destination =session.createqueue ("Test-queue");
MessageProducer producer =session.createproducer (destination); for (int i = 0; i < num_messages_to_send; i++) {TextmEssage message =session.createtextmessage ("message#" + i);
SYSTEM.OUT.PRINTLN ("Sending message #" + i);
Producer.send (message);
Thread.Sleep (DELAY);
} producer.close ();
Session.close ();
} catch (Exception e) {System.out.println ("caught exception!");
} finally {if (connection! = null) {try {connection.close ();
} catch (JMSException e) {System.out.println ("Could not close an open connection ..."); }
}
}
}
}
Consumer Code:
public class Consumer {//private static final String Broker_url = "tcp://192.168.1.106:61616";
private static final String Broker_url = "tcp://192.168.1.107:61617";
private static final Boolean non_transacted = false;
Private static final long TIMEOUT = 20000;
public static void Main (string[] args) {String url = broker_url;
if (Args.length > 0) {url = Args[0].trim ();
} System.out.println ("\nwaiting to receive messages ... would timeout after" + timeout/1000 + "s");
Activemqconnectionfactoryconnectionfactory = new Activemqconnectionfactory ("admin", "admin", url);
Connection Connection = null;
try {connection = connectionfactory.createconnection ();
Connection.start ();
Session session =connection.createsession (non_transacted, Session.auto_acknowledge);
Destination Destination =session.createqueue ("Test-queue"); Messageconsumer consumeR =session.createconsumer (destination);
int i = 0;
while (true) {message message =consumer.receive (TIMEOUT); if (message = null) {if (message instanceof textmessage) {String Text = (Te
xtmessage) message). GetText (); System.out.println ("Got" + i++ + ".
Message: "+ text");
}} else {break;
}} consumer.close ();
Session.close ();
} catch (Exception e) {System.out.println ("caught exception!");
} finally {if (connection! = null) {try {connection.close ();
} catch (JMSException e) {System.out.println ("Could not close an open connection ..."); }
}
}
}
}
2. After sending the queue message, view the ACTIVEMQ Web page information:
You can see from the Web page that the queue information has been stored:
3, through the consumer to take another machine in the cluster queue data, you can take
At this point, the ACTIVEMQ cluster configuration is complete