面试题答案
一键面试队列的镜像设置
- RabbitMQ集群配置:
- 在RabbitMQ集群节点上,通过命令行工具或管理界面设置镜像队列。例如,使用命令行设置镜像队列策略:
上述命令将所有队列(匹配rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
^
正则表达式,即所有队列)设置为镜像队列,ha - mode
为all
表示在所有节点上镜像。也可以设置更灵活的策略,比如只在部分节点镜像:rabbitmqctl set_policy ha-two "^" '{"ha - mode":"nodes","ha - params":["rabbit@node1","rabbit@node2"]}'
- C#代码层面:C#代码与镜像队列交互和普通队列基本一致,因为对客户端来说,镜像队列看起来和普通队列一样。例如,使用
RabbitMQ.Client
库发送消息:using RabbitMQ.Client; using System.Text; class Program { static void Main() { var factory = new ConnectionFactory() { HostName = "your - hostname" }; using (var connection = factory.CreateConnection()) using (var channel = connection.CreateModel()) { channel.QueueDeclare(queue: "your - queue - name", durable: true, exclusive: false, autoDelete: false, arguments: null); string message = "Hello World!"; var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange: "", routingKey: "your - queue - name", basicProperties: null, body: body); Console.WriteLine(" [x] Sent {0}", message); } } }
负载均衡策略
- RabbitMQ集群配置:RabbitMQ内置了负载均衡机制。当多个消费者连接到集群时,RabbitMQ会自动将消息分发给不同的消费者。可以通过
x - queue - master - locator
参数进一步优化负载均衡。例如,将队列的主节点定位在特定节点上:rabbitmqctl set_policy ha - master - locator "^" '{"ha - mode":"exactly","ha - params":2,"x - queue - master - locator":"min - masters"}'
min - masters
策略会将队列主节点定位在拥有最少主队列的节点上。 - C#代码层面:消费者代码只需要正常连接到集群并消费消息。例如:
using RabbitMQ.Client; using RabbitMQ.Client.Events; using System.Text; class Program { static void Main() { var factory = new ConnectionFactory() { HostName = "your - hostname" }; using (var connection = factory.CreateConnection()) using (var channel = connection.CreateModel()) { channel.QueueDeclare(queue: "your - queue - name", durable: true, exclusive: false, autoDelete: false, arguments: null); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var body = ea.Body.ToArray(); var message = Encoding.UTF8.GetString(body); Console.WriteLine(" [x] Received {0}", message); }; channel.BasicConsume(queue: "your - queue - name", autoAck: true, consumer: consumer); Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } } }
处理脑裂问题
- RabbitMQ集群配置:
- 确保集群节点之间网络稳定。可以通过增加网络冗余(如多网卡、冗余网络链路)来减少网络故障导致脑裂的可能性。
- 合理设置
cluster_partition_handling
参数。可以将其设置为pause_minority
,当发生脑裂时,少数派节点会暂停服务,避免数据不一致。在rabbitmq.config
文件中设置:
[ {rabbit, [ {cluster_partition_handling, pause_minority} ]} ].
- C#代码层面:在C#代码中,需要处理连接异常。例如,当连接因为脑裂等网络问题中断时,重新连接到集群:
using RabbitMQ.Client; using RabbitMQ.Client.Exceptions; using System; using System.Text; using System.Threading; class Program { static IConnection connection; static IModel channel; static void Main() { Connect(); while (true) { try { // 正常的消息发送或接收操作 channel.QueueDeclare(queue: "your - queue - name", durable: true, exclusive: false, autoDelete: false, arguments: null); string message = "Hello World!"; var body = Encoding.UTF8.GetBytes(message); channel.BasicPublish(exchange: "", routingKey: "your - queue - name", basicProperties: null, body: body); Console.WriteLine(" [x] Sent {0}", message); } catch (BrokerUnreachableException) { Console.WriteLine("Connection lost, trying to reconnect..."); Connect(); } Thread.Sleep(1000); } } static void Connect() { var factory = new ConnectionFactory() { HostName = "your - hostname" }; while (true) { try { connection = factory.CreateConnection(); channel = connection.CreateModel(); break; } catch (BrokerUnreachableException) { Console.WriteLine("Could not connect, retrying in 5 seconds..."); Thread.Sleep(5000); } } } }