RabbitMQ cluster inter-network messaging migration

Demand background

The message RabbitMQ cluster at the same VPC Ali cloud migration from one segment to another segment cluster cluster. Messaging middleware is a message for immediate consumption, why are historical news, because it is a question left over by history. Therefore, to migrate

The entire network topology is as follows

note:

If the network for cross-VPC

1. Ensure that each host network interworking

2. configure each host name

Security groups on both sides of the direction of development: 15672,25672,5672,4369 port

No cause problems in joining the cluster

Resource List

CPU name

IP addresses

Character

Remark

node171

172.20.0.171

Old MQ cluster _1

 

node172

172.20.0.172

Old MQ cluster _2

 

by node 173

192.168.0.173

New in MQ cluster _1

 

node174

192.168.0.174

The new MQ cluster _2

 

Infrastructure software and information environment

Erlang: Erlang / OTP 20 [ore-9.3.3.3]

RabbitMQ:rabbitmq_server-3.7.8

Cluster deployment

node171, node172 up the cluster A

node173, node174 up the cluster B

Here's a little deployment environment

Create a test account

[Operation] in the node171

rabbitmqctl add_user root root123

rabbitmqctl add_vhost kcvhost

rabbitmqctl set_permissions -p kcvhost root  ".*" ".*" ".*"

rabbitmqctl add_user admin admin123

rabbitmqctl set_permissions -p kcvhost admin  ".*" ".*" ".*"

rabbitmqctl set_user_tags admin administrator

rabbitmq-plugins enable rabbitmq_management

rabbitmqctl stop_app

rabbitmqctl start_app

Generate test data

News producer Code:

private static final String EXCHANGE_NAME = "exchange_test_3";
private static final String ROUTING_KEY = "routingkey_demo";
private static final String QUEUE_NAME = "queue_test_3";
private static final String IP_ADDRESS = "172.20.0.171";
private static final int PORT = 5672; //RabbitMQ服务默认端口号为5672


static void main public (String [] args) throws IOException, a TimeoutException, {InterruptedException
the ConnectionFactory Factory the ConnectionFactory new new = ();
factory.setHost (IP_ADDRESS);
factory.setPort (PORT);
factory.setUsername ( "the root");
Factory. the setPassword ( "root123");
connection connection factory.newConnection = (); // create a connection
channel channel = connection.createChannel (); // Create channel
 // Create a type = "direct", persistent, non-automatic deletion switch
channel.exchangeDeclare (EXCHANGE_NAME, "Direct", to true, false, null);
// create a persistent, non-exclusive, non-automatic deletion queue
channel.queueDeclare (qUEUE_NAME, true, false, false, null);
// switch to the queue via the routing key bindings
channel.queueBind (queue_name, EXCHANGE_NAME, ROUTING_KEY);
// send a persistent message: hello world!
for (int I = 1; I <= 100000; I ++) {
String MSG = "_1 exchanger and queue 1 binding: the Message _" + I;
channel.basicPublish (EXCHANGE_NAME, ROUTING_KEY, MessageProperties.PERSISTENT_TEXT_PLAIN, Msg.getBytes ( ));
}
// close resource
channel.close ();
Connection.close ();
 
}
 
}


Consumer Code

package com.zjkj.rabbitmq.demo;
 
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
 
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Address;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
 
/**
 * 消息的消费者
 * @author zjkj
 *
 */
public class Rabbitmq_Consumer {
 
private static final String QUEUE_NAME = "queue_test_3";
private static final String IP_ADDRESS = "192.168.6.171";
private static final  int PORT = 5672;


static void main public (String [] args) throws IOException, a TimeoutException, {InterruptedException
the Address [] = new new the Address Addresses [] {
new new the Address (IP_ADDRESS, PORT)
};
the ConnectionFactory Factory the ConnectionFactory new new = ();
factory.setUsername ( "the root ");
factory.setPassword (" root123 ");
// connection here with the demo producers slightly different, note the difference
connection connection = factory.newConnection (addresses); // create a connection
final Channel channel = connection.createChannel (); // Create channel
channel.basicQos (64); // set up the client has not been received ack message number


/ **
 * This use of inheritance DefaultConsumer way to achieve consumption, have had experience with RabbitMQ developer
 * may prefer to use QueueingConsumer way to achieve consumption
 * Use QueueingConsumer because there will be some problems.
 * While RabbitMQ Java client begins QueueingConsumer 4.0.0 @Deprecated a marked
 * /
Consumer Consumer = new new DefaultConsumer (Channel) {
@Override
public void handleDelivery (String consumerTag, Envelope Envelope, AMQP.BasicProperties Properties, byte [] body)
  throws IOException {
System.out.println ( "the recv Message:" + new new String (body));
the try {
TimeUnit.SECONDS.sleep (. 1);

the catch} (InterruptedException E) {
e.printStackTrace ();
}
channel.basicAck (envelope.getDeliveryTag (), to false);
}
};
channel.basicConsume (queue_name, to true, Consumer);
// wait for a callback function completes after, Close the resource
TimeUnit.SECONDS.sleep (. 5);
channel.close ();
Connection.close ();
 
}
 
}


Such as the number of users view the cluster, the number of switches, the number of queues, etc.

[root@node171 rabbitmq]# rabbitmqctl list_users

Listing users ...

admin  [monitoring]

guest  [administrator]

root    []

[root@node171 rabbitmq]# rabbitmqctl list_exchanges

Listing exchanges for vhost / ...

amq.topic Topic

amq.headers    headers

exchange_test_3 direct

amq.direct      direct

exchange_test_2 direct

amq.rabbitmq.trace      topic

amq.match headers

        direct

exchange_test_1 direct

amq.fanout fanout

[root@node171 rabbitmq]# rabbitmqctl list_queues

Timeout: 60.0 seconds ...

Listing queues for vhost / ...

queue_test_3    100000

queue_test_2    200

queue_test_1    10000

Migration Scenarios

Migration Steps

1. Stop all producers and consumers of applications

2. The machine cluster B is added sequentially one of a cluster A, and confirm that all queues complete image

3. A culling cluster in one machine

4. Application of the cluster B to point

Scenario 1 [feasible]

The cluster B is added to the cluster A of a machine, and then the cluster B is another machine he has joined the cluster, the cluster A and then removed in one machine, and then remove the cluster A in another machine

This program is for ordinary RabbitMQ cluster that is, Cluster mode is invalid

1. Stop all connected to the cluster A

2. B is a cluster node to the cluster A

The .erlang.cookie value of the cluster A to cluster B copies of node173

[root@node171 rabbitmq]# cat .erlang.cookie

ORMTFBMHOXOGFKRLQSPU[root@node171 rabbitmq]#

[root@node173 plugins]# cp /var/lib/rabbitmq/.erlang.cookie  /var/lib/rabbitmq/erlang.cookie.bak

[root@node173 plugins]# chmod 700 /var/lib/rabbitmq/.erlang.cookie

 [root@node173 plugins]# vi /var/lib/rabbitmq/.erlang.cookie


ORMTFBMHOXOGFKRLQSPU
 

[root@node173 plugins]# chmod 400 /var/lib/rabbitmq/.erlang.cookie

[root@node173 plugins]# ls -lrth /var/lib/rabbitmq/.erlang.cookie

-r-------- 1 rabbitmq rabbitmq 21 Oct 24 18:51 /var/lib/rabbitmq/.erlang.cookie

3. node173 cluster B is added to the cluster A,

[root@node173 rabbitmq]# service rabbitmq-server start

Redirecting to /bin/systemctl start  rabbitmq-server.service

[root@node173 rabbitmq]# rabbitmqctl stop_app

Stopping rabbit application on node mq_173@node173 ...

[root@node173 rabbitmq]# rabbitmqctl reset

Resetting node mq_173@node173 ...

[root@node173 rabbitmq]# rabbitmqctl join_cluster mq171@node171

Clustering node mq_173@node173 with mq171@node171

[root@node173 rabbitmq]# rabbitmqctl start_app

Starting node mq_173@node173 ...

 completed with 3 plugins.

4. The same method as in the cluster B of the cluster A is added to the node174

[root@node174 rabbitmq]# rabbitmqctl cluster_status

Cluster status of node mq_174@node174 ...

[{nodes,[{disc,[mq_174@node174]}]},

 {running_nodes,[mq_174@node174]},

 {cluster_name,<<"mq_174@node174">>},

 {partitions,[]},

 {alarms,[{mq_174@node174,[]}]}]

 [root@node174 rabbitmq]# rabbitmqctl stop_app

Stopping rabbit application on node mq_174@node174 ...

[root@node174 rabbitmq]# rabbitmqctl reset

Resetting node mq_174@node174 ...

[root@node174 rabbitmq]# rabbitmqctl join_cluster mq171@node171

Clustering node mq_174@node174 with mq171@node171

[root@node174 rabbitmq]# rabbitmqctl start_app

Starting node mq_174@node174 ...

 completed with 0 plugins.

  5. A cluster of cluster node171 removed

[root@node171 rabbitmq]# rabbitmqctl stop

Stopping and halting node mq171@node171 ...

Then visit the Web cluster management node172

The same Web management interface on node173 View

So far for the average cluster model, this approach is not acceptable.

Scenario 2 [feasible]

If mirroring RabbitMQ queue, the data migration message to the cluster A, cluster B,

A cluster of node171, node172 queue mirroring

A mirror image queue build cluster environment

1. A first cluster of the cluster added node172

[Operation] on node172

[root@node172 ~]# rabbitmqctl stop_app

Stopping rabbit application on node mq172@node172 ...

[root@node172 ~]# rabbitmqctl reset

Resetting node mq172@node172 ...

 [root@node172 ~]# rabbitmqctl join_cluster mq171@node171

Clustering node mq172@node172 with mq171@node171

ra[root@node172 ~]# rabbitmqctl start_app

Starting node mq172@node172 ...

2. Set the mirror policy

[Operation] on node171

[root@node171 ~]# rabbitmqctl set_policy ha-all -p kcvhost "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}'

Setting policy "ha-all" for pattern "^" to "{"ha-mode":"all","ha-sync-mode":"automatic"}" with priority "0" for vhost "kcvhost" ...

 

[root@node171 ~]# rabbitmqctl set_policy rabbit_mirror "^" '{"ha-mode":"all"}'

Setting policy "rabbit_mirror" for pattern "^" to "{"ha-mode":"all"}" with priority "0" for vhost "/" ...

Mirroring queue migration starts in cluster A

1. Stop all message producer and consumer related applications and services

2. Stop all machines in the cluster A and backup of the original data

 [Node171, node172] must operate

Node172 performed as follows:

[root@node172 ~]# service rabbitmq-server stop

Redirecting to /bin/systemctl stop  rabbitmq-server.service

[root@node172 ~]# cd /var/lib/rabbitmq/

[root@node172 rabbitmq]# ls

mnesia

[root@node172 rabbitmq]# cp -rf mnesia mnesia.20181025.bak

[root@node172 rabbitmq]# service rabbitmq-server start

Redirecting to /bin/systemctl start  rabbitmq-server.service

node171 performed as follows:

[root@node171 ~]# service rabbitmq-server stop

Redirecting to /bin/systemctl stop  rabbitmq-server.service

[root@node171 ~]# cd /var/lib/rabbitmq/

[root@node171 rabbitmq]# cp -rf mnesia mnesia.20181025.bak

[root@node171 rabbitmq]# service rabbitmq-server start

Redirecting to /bin/systemctl start  rabbitmq-server.service

2. First node173 machine cluster B is added to the cluster A,

[root@node173 network-scripts]# service rabbitmq-server stop

Redirecting to /bin/systemctl stop rabbitmq-server.service

[root@mq04 rabbitmq]# cp -rf /var/lib/rabbitmq /var/lib/rabbitmq.bak

[root@mq04 rabbitmq]# cd /var/lib/rabbitmq

[root@mq04 rabbitmq]# rm -rf .erlang.cookie  mnesia/

[root@mq01 rabbitmq]# scp .erlang.cookie  root@mq04:/var/lib/rabbitmq

The authenticity of host 'mq04 (192.168.0.232)' can't be established.

ECDSA key fingerprint is SHA256:zgAicKOpvRLLCyhdUbpNvyanKYrPt/Pp9g+Sdq9mAoo.

ECDSA key fingerprint is MD5:15:7d:1e:c2:86:d5:4a:40:63:df:f5:4e:65:c4:24:62.

Are you sure you want to continue connecting (yes/no)? yes

Warning: Permanently added 'mq04' (ECDSA) to the list of known hosts.

root@mq04's password:

Permission denied, please try again.

root@mq04's password:

.erlang.cookie                                                                  100%  20    19.6KB/s  00:00

[root@mq04 rabbitmq]# chmod 400 .erlang.cookie

[root@mq04 rabbitmq]# chown -R rabbitmq:rabbitmq .erlang.cookie

[root@mq04 rabbitmq]# service rabbitmq-server start

Redirecting to /bin/systemctl start rabbitmq-server.service

[root@mq04 rabbitmq]# rabbitmqctl stop_app

Stopping rabbit application on node mq04@mq04 ...

[root@mq04 rabbitmq]# rabbitmqctl reset

Resetting node mq04@mq04 ...

For Ali cloud ECS must first open a temporary port security group 15672,25672,5672,4369

[root@node173 network-scripts]# rabbitmqctl join_cluster mq171@node171

Clustering node mq_173@node173 with mq171@node171

[root@node173 network-scripts]# rabbitmqctl start_app

Starting node mq_173@node173 ...

 completed with 3 plugins.

3. B then node174 machine cluster to the cluster A,

 Using the same method as above, is added to the cluster to node174

4. A cluster excluding the node171, node172 machine

Execution on Node172

[root@mq02 rabbitmq]# rabbitmqctl stop_app

Stopping rabbit application on node mq02@mq02 ...

[root@mq02 rabbitmq]# service rabbitmq-server stop

Redirecting to /bin/systemctl stop rabbitmq-server.service

[root@mq02 rabbitmq]# cp -rf /var/lib/rabbitmq /var/lib/rabbitmq.bak

[root@mq02 rabbitmq]# service rabbitmq-server start

Redirecting to /bin/systemctl start rabbitmq-server.service

[root@mq02 rabbitmq]# rabbitmqctl stop_app

Stopping rabbit application on node mq02@mq02 ...

[root@mq02 rabbitmq]# rabbitmqctl reset

Resetting node mq02@mq02 ...

The same command executed on the same node171

Mirroring the queue for the cluster, this is feasible

Guess you like

Origin www.linuxidc.com/Linux/2019-07/159481.htm