如何从发布者和消费者方面使用rabbitmq进行恢复

建立

使用官方的RabbitMQ docker容器并通过运行启动队列

docker run -d --hostname my-rabbit --name some-rabbit -p 808015672 -p 56725672 rabbitmq:3-management

在发布者拥有队列的那一刻,通过启动它,将创建队列并使用他们自己的路由键定义两个主题。

发布者

using System;
using RabbitMQ.Client;
using System.Text;
using System.Threading;

namespace publisher
{
    class Program
    {
        static void Main(string[] args)
        {
            Random rnd = new Random();
            Console.WriteLine("Starting publisher!");
            var factory = setupConnection();

            using(var connection = factory.CreateConnection())
            using(var channel = connection.CreateModel()){ 
                //队列
                //在声明队列时,请记住考虑队列应具有的持久性以及是否应该是排他性队列(Exclusive Queue)。
                // channel.QueueDeclare(queue: "pingpong", 
                //                      durable: false,
                //                      exclusive: false,
                //                      autoDelete: false,
                //                      arguments: null);

                channel.QueueDeclare(queue: "pingpongA",
                                     durable: true,
                                     exclusive: false,
                                     autoDelete: false,
                                     arguments: null);

                channel.QueueDeclare(queue: "pingpongB",
                                     durable: false,
                                     exclusive: false,
                                     autoDelete: false,
                                     arguments: null);

                //Topic
                channel.ExchangeDeclare(exchange: "pingpong",
                                        type: "topic");

                //使用Topic绑定特定队列并定义路由键
                channel.QueueBind(queue: "pingpongA",
                                  exchange: "pingpong",
                                  routingKey: "topicA");

                channel.QueueBind(queue: "pingpongB",
                                  exchange: "pingpong",
                                  routingKey: "topicB");

                while (true)
                {
                    string messageTopicA = Guid.NewGuid() + ", Hello TopicA!, " + DateTime.Now;
                    var bodyTopicA = Encoding.UTF8.GetBytes(messageTopicA);
                    string messageTopicB = Guid.NewGuid() + ", Hello TopicB!, " + DateTime.Now;
                    var bodyTopicB = Encoding.UTF8.GetBytes(messageTopicB);
                    try
                    { 
                        //队列
                        //对于每个队列,请考虑使用路由键来处理请求/响应模式。 这将使用相同的topic,但在该topic上创建特定的路由。
                        // channel.BasicPublish(exchange: "",
                        //             routingKey: "sent",
                        //             basicProperties: null,
                        //             body: body);
                        //考虑做发布者确认,这将引入开销,因为需要维护事务,有关详细信息,请参阅https://www.rabbitmq.com/confirms.html


                        //Topic
                        channel.BasicPublish(exchange: "pingpong",
                                        routingKey: "topicA",
                                        basicProperties: null,
                                        body: bodyTopicA);

                        channel.BasicPublish(exchange: "pingpong",
                                        routingKey: "topicB",
                                        basicProperties: null,
                                        body: bodyTopicB);

                        //生成一些随机行为
                        Console.WriteLine(" [x] Sent {0}", messageTopicA);
                        Console.WriteLine(" [y] Sent {0}", messageTopicB);
                        Thread.Sleep(rnd.Next(2000, 6000));
                    } 
                    //捕获生成的异常,这是在网络或rabbitmq更改下抛出的。 该异常包含一条消息,有时可以解释抛出的异常类型。
                    catch (RabbitMQ.Client.Exceptions.AlreadyClosedException)
                    {
                        Console.WriteLine("Connection is down, trying to reconnect.");
                    }

                }
            }

        }

        static ConnectionFactory setupConnection()
        {
            var factory = new ConnectionFactory();
            factory.HostName = "localhost";

            //设置恢复选项
            factory.AutomaticRecoveryEnabled = true;
            factory.TopologyRecoveryEnabled = true;

            //来自标准文档
            factory.RequestedHeartbeat = 60;

            //随机化连接间隔,因此多个连接不会尝试同时重新连接。
            Random rnd = new Random();
            factory.NetworkRecoveryInterval = TimeSpan.FromSeconds(rnd.Next(15, 45));


            return factory;
        }
    }
}

消费者

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;

namespace consumer
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Starting Consumer!");
            var factory = setupConnection();

            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {

                //队列
                //声明确定队列存在,考虑发布者或消费者是否应该创建队列
                // channel.QueueDeclare(queue: "pingpongA",
                //                      durable: true,
                //                      exclusive: false,
                //                      autoDelete: false,
                //                      arguments: null);

                // channel.QueueDeclare(queue: "pingpongB",
                //                      durable: false,
                //                      exclusive: false,
                //                      autoDelete: false,
                //                      arguments: null);

                // var consumer = new EventingBasicConsumer(channel);
                // consumer.Received += (model, ea) =>
                // {
                //     var body = ea.Body;
                //     var message = Encoding.UTF8.GetString(body);
                //     Console.WriteLine(" [x] Received {0}", message);
                // };

               //记住考虑自动确认是否应该为真,首选是完全处理请求然后确认。
                // channel.BasicConsume(queue: "pingpong",
                //                      autoAck: true,
                //                      consumer: consumer);

                //Topic
                channel.ExchangeDeclare(exchange: "pingpong", type: "topic");

                //使用Topic绑定特定队列并定义路由键
                // channel.QueueBind(queue: "pingpongA",
                //                   exchange: "pingpong",
                //                   routingKey: "topicA");

                // channel.QueueBind(queue: "pingpongB",
                //                   exchange: "pingpong",
                //                   routingKey: "topicB");

                //生成消费者
                var consumer = new EventingBasicConsumer(channel);
                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body);
                    var routingKey = ea.RoutingKey;
                    Console.WriteLine(" [x] Received '{0}':'{1}'",
                                    routingKey,
                                    message);
                    channel.BasicAck(ea.DeliveryTag, false);
                };

                //启动两个不同队列的消费者
                channel.BasicConsume(queue: "pingpongA",
                                 autoAck: false,
                                 consumer: consumer);

                channel.BasicConsume(queue: "pingpongB",
                                 autoAck: false,
                                 consumer: consumer);
                Console.ReadLine();
            }
        }

        static ConnectionFactory setupConnection()
        {
            var factory = new ConnectionFactory();
            factory.HostName = "localhost";

            //AutomaticRecoveryEnabled  断线重连,也就是如果当前的连接断开了,将会尝试重连

            //TopologyRecoveryEnabled 重连后恢复当前的工作进程,比如channel、queue、发布的消息进度等 //设置重新声明交换器,队列等信息。
            //设置恢复选项
            factory.AutomaticRecoveryEnabled = true;
            factory.TopologyRecoveryEnabled = true;

            //来自标准文档
            factory.RequestedHeartbeat = 60;

            //随机化连接间隔,因此多个连接不会尝试同时重新连接。
            Random rnd = new Random();
            //设置每15-45s ,重试一次
            factory.NetworkRecoveryInterval = TimeSpan.FromSeconds(rnd.Next(15, 45));

            return factory;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值