zoukankan      html  css  js  c++  java
  • 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();

    这样才不会直接消失;

  • 相关阅读:
    php解决与处理网站高并发 大流量访问的方法
    mysql事务和锁InnoDB
    从一个死锁看mysql innodb的锁机制
    Git如何删除自己创建的项目
    公众号的坑
    字符串转Unicode码
    字符串转UTF-8码(%开头)
    git介绍和使用
    ng2中文文档地址
    两个数组的排序方法
  • 原文地址:https://www.cnblogs.com/maanshancss/p/7953420.html
Copyright © 2011-2022 走看看