RabbitMQ.NET In Window Service

工作中要求使用RabbitMQ,以Windows Service 模式启动,中间有遇到一些问题,网上大部分博客有误导倾向, 在这里做一个简单的记录,以免后面的人走坑;

1.

自动重新连接,不需要手动处理自动连接   

AutomaticRecoveryEnabled = true //断开自动重新连接

2.因为是Windows Service  ,与控制台程序不同,若是像Demo中直接使用Received ,那么可能只会接收一次消息,然后程序执行完毕退出

后来我就使用了While(true),当时测试能解决问题,后来发现运行久了没有消息接收会时不时的断开连接,出现错误消息提示:

【ErrorType】System.IO.EndOfStreamException
【TargetSite】T Dequeue()
【Message】SharedQueue closed
【Source】RabbitMQ.Client
【StackTrace】   at RabbitMQ.Util.SharedQueue`1.Dequeue()
   at ******

开始以为是RabbitMQ.Net的版本问题,观察对比了几次发现并不是这个问题,高版本的程序也存在这个问题,低版本的也有,而且只有在Windows Service中才会有这个错误,直接Debug测试时正常的,

这个错误很容易被忽略,应该感觉自己Debug没有问题,怎么到客户那里Windows Service就出错了,会以为是安装包或者是客户电脑的问题,后来发现是因为While(true)的问题;

网上这个问题的很多答案都是说是确认消息 自动确认又手动确认,反正很多,后来发现是没有用事件的原因;

在http://www.cnblogs.com/maanshancss/p/7905976.html 也提到了不用while(true),我开始还以为只是异常处理部分作者没有处理呢,实际上需要另外一种写法,针对的Window Service 的,文章后面会贴出来源码;

3.需要理解XP和Win7 etc. 不同操作系统中 Window Service 账户的区别

4.参考http://www.cnblogs.com/maanshancss/p/7905976.html

中的内容,有些是需要注意的

try
            {
   
                string amqEndpoint = System.Configuration.ConfigurationManager.AppSettings["MQEndpoint"].ToString();
                string amqUsername = System.Configuration.ConfigurationManager.AppSettings["MQUserName"].ToString();
                string amqPassword = System.Configuration.ConfigurationManager.AppSettings["MQPassword"].ToString();
                var amqName = System.Configuration.ConfigurationManager.AppSettings["MQName"].ToString();

                var exchangeType = "direct";
                var uri = new Uri("amqp://" + amqEndpoint + "/");
                var factory = new ConnectionFactory
                {
                    UserName = amqUsername,
                    Password = amqPassword,
                    RequestedHeartbeat = 60,
                    Endpoint = new AmqpTcpEndpoint(uri),
                    AutomaticRecoveryEnabled = true //断开自动重新连接
                };

   


                var connection = factory.CreateConnection();
                var channel = connection.CreateModel();
                channel.QueueDeclare(queue: amqName,
                                     durable: true,
                                     exclusive: false,
                                     autoDelete: false,
                                     arguments: null);

                //创建基于该队列的消费者,绑定事件
                var consumer = new EventingBasicConsumer(channel);
                //绑定消费者
                channel.BasicConsume(queue: amqName, //队列名
                                     noAck: false,    //false:手动应答;true:自动应答
                                     consumer: consumer);
          

                consumer.Received += (model, ea) =>
                {
                    try
                    {
                        //TOOD 验证程序退出后消费者是否退出去了
                        var body = ea.Body; //消息主体
                        var message = Encoding.UTF8.GetString(body);
                        Logger.WriteAndShowLog(message);
                      //  Method(message);
                        channel.BasicAck(ea.DeliveryTag, false);
                    }
                    catch (RabbitMQ.Client.Exceptions.OperationInterruptedException ex1)
                    {
                        Logger.CreateErrorLog(ex1, "OperationInterruptedException");
                        Thread.Sleep(5000);
                        channel.BasicNack(ea.DeliveryTag, false, true);
                    }
                    catch (Exception ex)
                    {
                        Logger.CreateErrorLog(ex, "Exception");
                        Thread.Sleep(5000);
                        channel.BasicNack(ea.DeliveryTag, false, true);
                    }
                };
              
                Console.ReadLine();
            }
            catch (System.Exception ex)
            {
                Logger.CreateErrorLog(ex);
                Console.ReadLine();
            }

与Demo不同的地方


var connection = factory.CreateConnection();
var channel = connection.CreateModel();

这样才不会直接消失;

 

posted @ 2017-12-02 09:29  maanshancss  阅读(945)  评论(1编辑  收藏  举报