Grasp the RabbitMQ (five) - to build a highly available cluster RabbitMQ

  RabbitMQ cluster is dependent on erlang cluster, and the cluster is erlang by .erlang.cookie text communicate certified parts, so we use RabbitMQ cluster only need to configure .erlang.cookie file. RabbitMQ below simply show you build high availability clusters, with a simple to use C # RabbtiMQ driven clusters of small chestnut.

1 building RabbitMQ High Availability Cluster

  First, prepare three devices, where the use of virtual machine three Centos7, and test each virtual machine can not ping each other, if you can ping each other, then on each virtual machine were installed RabbitMQ, you can refer to the first chapter of the installation method .

Step 1 modified Host Configuration

   In order to facilitate mutual visits between machines, three centos perform   vim / etc / hosts  , add the following configuration (Note to modify their own IP devices):

192.168.70.129 rabbitmq1
192.168.70.131 rabbitmq2
192.168.70.133 rabbitmq3

  Generally, hosts file as follows:

Step 2: Modify .erlang.cookie file

  Modify consistent .erlang.cookie three devices in the key. If the front mounting method, .erlang.cookie location  /var/lib/rabbitmq/.erlang.cookie  (file not found using other installation, you can use the command   Find / -name ' .erlang.cookie '  find the file location). Here three virtual machines are used 192.168.70.129 key of key (value CRRQPKHDXEEIUJUOGYKN), execute commands on the other two devices:  Vim / var /lib/rabbitmq/.erlang.cookie  , modify the contents of the file CRRQPKHDXEEIUJUOGYKN. When you modify the permissions If you encounter problems, executable command  chmod 600 /var/lib/rabbitmq/.erlang.cookie  after permission to modify the file is writable, modify the content is complete, execute the command  chmod 400 / var / lib / rabbitmq /. erlang.cookie  put into read-only file again.

  Upon completion of the two-step top, erlang cluster build better, restart all the equipment can be. Execute commands on a virtual machine rabbitmq1 node  rabbitmqctl cluster_status  View cluster status:

 Step 3: Add / remove nodes

Add Nodes

  Add nodes to the cluster to rabbitmq2, execute the following command in rabbitmq2 node:

rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster rabbit@rabbit1
rabbitmqctl start_app

  After execution, view the cluster status, see rabbitmq2 already in the cluster, as follows:

  Repeat the procedure above, the rabbitmq3 also added to the cluster, execute the following command in rabbitmq3 node:
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl join_cluster rabbit@rabbit2
rabbitmqctl start_app
  View cluster status, rabbitmq3 also the cluster, as follows:  

  Then we open any node in the Web management interface, shown below, see the cluster has been configured:

Delete nodes
  to delete a node from the cluster is simple, reset it to the node. Such as deleting rabbitmq3 node, execute the following command on rabbitmq3:
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app

  After execution, view the status of the cluster are as follows:

   Now build cluster is the default cluster ordinary, ordinary nodes in the cluster can share the cluster exchange, routingKey and queue, but the queue of messages stored only in the first node in a statement queue. Consumers may be any node of other nodes message consumer, such as consumer connects rabbitmq1 consumer node (Connection is established code, rabbitmq1 used IP) may be the message queue node rabbitmq2 myqueue2 consumption in the message transmission process is : myqueue2 in the message transmission rabbitmq2 to rabbtimq1, rabbitmq1 node then sends messages to the consumer. Because the queue of messages stored only in the first node in a statement queue, so there is a question: If one node node hang up, you can only wait for the node to reconnect to continue processing the message within the node (if not set persistent, then hang up after node message directly lost). Below, the node rabbitmq1 hang, MyQueue Queuing is down, can not be accessed.

  For the top, we might think: If you can make rabbitmq node in the same cluster as the node redis, each node keeps all messages, such as making rabbitmq1 not only save his own message queue myqueue also save other nodes queue myqueue2 and myqueue3 messages, rabbitmq2 and rabbitmq3 node is the same, so do not worry about the downtime. rabbitmq also provides such functions: the mirror queue. A mirror queue by the master and a plurality of slave form, using a mirror queue messages are automatically synchronized between the mirror node, rather than pulling the temporary data fetch the consumer.

Step 4: Queue Configuration Mirror

  rabbitmq configure mirroring the queue is very simple, we have to run the following command in any node of a node can be completed configuring the Mirror queue (of course, you can also add policy on the Web Management Interface):

rabbitmqctl set_policy HA-All " ^ My " '{ " HA-MODE " : " All " , " HA-Sync-MODE " : " Automatic " }'
 # HA-All : a policy name; 
# ^ My : matching character only representative of a match all ^, ^ abc abc beginning to match the queue name or Exchange; 
# HA-mODE : synchronous mode, a total of three modes: 
#     ①all- all (all nodes are synchronized message), 
#     ②exctly - Specifies the number of nodes (ha-params configuration required parameter, such as the int type 2, randomly selected two nodes in the cluster synchronization message) 
#     ③nodes- specify a particular node (ha-params configuration required parameter, an array For example, type [ "rabbit @ rabbitmq1", " rabbit @ rabbitmq2"], Explicitly specify synchronization message on both nodes).

  Open Web management interface, the effect is expressed as follows if the queue have configured the mirror. The master node is currently myqueue rabbitmq1:

  If the first statement of the queue node (master) linked to the other nodes will automatically become master, the master is shown above myqueue rabbitmq1, stopped after rabbtmq1, the following results: rabbitmq2 become a master.

 

  We found that rabbitmq1 node hung up, rabbitmq2 automatically become a master myqueue of, myqueue will not fall down, you can normally add / remove / extract the message, which would address the issue of ordinary cluster downtime. Mirroring queue because the synchronization message to each node, it is more resource-intensive, the mirror is generally used at a relatively high reliability queue scene.

You can also configure other policies mirror the queue, but also to complete the command line configurations, some other chestnuts synchronous mode:

# Node named policy ha-twe, matching queue to exchange or "my" beginning, randomly selected image nodes in the cluster, synchronization is two 
rabbitmqctl set_policy HA-TWO " ^ My "     '{ " HA-MODE " : " exactly " , " HA-the params " : 2, " HA-Sync-MODE " : " Automatic " } '
 # policy named ha-nodes, or exchange to queue matching with "my", specifying rabbit and rabbit @ rabbitmq2 @ rabbitmq3 synchronization node 
rabbitmqctl set_policy HA-nodes " ^ My " \ '{ " HA-MODE " : "nodes","ha-params":["rabbit@rabbitmq2", "rabbit@rabbitmq3"]}'

Step 5: C # Driver RabbitMQ cluster

  Basically the same drive RabbitMQ cluster C # and C # RabbtiMQ drive single way, except that the use of the cluster, create a Connection is a host specified collection. Look at a simple chestnut:

Manufacturer Code:

        static  void the Main ( String [] args) 
        { 
            var Factory = new new the ConnectionFactory () 
            { 
                UserName = " WYY " , // User Name 
                Password = " 123456 " , // password 
                AutomaticRecoveryEnabled = to true , // Connection off, automatic reconnection 
            };
             // cluster of three nodes rabbitmq 
            List < String > = the hosts new new List < String> () { " 192.168.70.129 " , " 192.168.70.131 " , " 192.168.70.1233 " };
             // to a random node rabbitmq 
            the using ( var Connection = factory.CreateConnection (the hosts)) 
            { 
                // create a channel Channel 
                the using ( var Channel = connection.CreateModel ()) 
                { 
                    Console.WriteLine ( " producers ready .... " );
                     #region release message 100
                     for (int i = 0; i < 100; i++)
                    {
                        channel.BasicPublish(exchange: "myexchange",
                                             routingKey: "mykey",
                                             basicProperties: null,
                                             body: Encoding.UTF8.GetBytes($"第{i}条消息"));
                    }
                    #endregion
                }
            }
            Console.ReadKey();
        }

Consumer Code:

        static  void the Main ( String [] args) 
        { 
            var Factory = new new the ConnectionFactory () 
            { 
                UserName = " WYY " , // User Name 
                Password = " 123456 " , // password 
            };
             // three nodes in the cluster rabbitmq 
            List < String > = the hosts new new List < String > () { " 192.168.70.129 " , " 192.168.70.131" , " 192.168.70.1233 " };
             // to a random node rabbitmq 
            the using ( var Connection = factory.CreateConnection (the hosts)) 
            { 
                the using ( var Channel = connection.CreateModel ()) 
                { 
                    // use Qos, each receiving 1 The news 
                    channel.BasicQos (prefetchSize: 0 , prefetchCount: 2 , , Ltd. Free Join : false ); 
                    Console.WriteLine ( " consumer ready .... " );
                     #regionEventingBasicConsumer // definition of consumer                                       var Consumer = new new EventingBasicConsumer (Channel); 
                    consumer.Received + = (SENDER, EA) => 
                    { // process a message required 10s time 
                        the Thread.Sleep ( 1000 );
                         // display a confirmation message 
                        channel. BasicAck (deliveryTag: ea.DeliveryTag, Multiple: to false ); 
                        Console.WriteLine ($ " ! message processing [{Encoding.UTF8.GetString (ea.Body)}] complete " ); 
                    }; // process the message

                    
                    
                        
                    
                    channel.BasicConsume(queue: "myqueue",
                                           autoAck: false,
                                           consumer: consumer);
                    Console.ReadKey();
                    #endregion
                }
            }
        }

   The implementation of these two applications, the results are as follows:

 

   Here RabbtMQ to build a cluster came to an end, there is a small problem: RabbitMQ cluster load balancing is not supported by default. We can according to the performance of the device, using Qos to individual consumers specify the appropriate maximum number of sending, so you can achieve load balancing to some extent. Friends of the Park also has load balancing RabbitMQ cluster by Haproxy , small partners who are interested can look into why the use of Haprpxy instead Ngnix it? This is because Haproxy support four (tcp, udp, http, etc.) and seven (http, https, email, etc.) load balancing, load balancing and Nginx supports only seven, and Rabbitmq by tcp transmission. This section also RabbitMQ series last one, if there is an error in the text, I hope that we can point out that I will be revised, thank you.

 

  

Guess you like

Origin www.cnblogs.com/wyy1234/p/10889742.html