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`.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 = ,
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();
channel.BasicNack(ea.DeliveryTag, false, true);
}
catch (Exception ex)
{
Logger.CreateErrorLog(ex, "Exception");
Thread.Sleep();
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();
这样才不会直接消失;
RabbitMQ.NET In Window Service的更多相关文章
- C# window service的创建
其实我也是第一次在博客园写博客,看到那些高手说自己要多动手写博客,于是乎自己也尝试尝试. 废话不多说.这几天在研究window service,通过查找各种大神写的博客,我终于成功的自己写出来了. 下 ...
- 创建 window service 定时任务
参考文章:http://www.cnblogs.com/jack-liang/archive/2011/05/20/2051743.html 前段时间做过一个项目,前端系统提供添加定时任务,后端系统要 ...
- Window Service 计划任务
在ASP.NET中创建计划任务,就我个人而言,用过两种方式,一种是用SQL Server创建,把写好的SSIS包导入SQL Server创建的任务中,设置好时间让它去执行.还有一种就是利用window ...
- window service 开发
为了便于window service的调试和开发. 我整理了一下代码,方便大家查阅 App.config 设置启动时间 timerStart-10点 interval-3600000 1小时检查一次 ...
- C# window Service实现调用有UI的应用程序(关于win xp以后的window系统)
我开发的系统中有一接口程序(这里就称Task,是一个C#的Console Application)经常无故的死掉,导致第二天的数据不能正常解析,所以,我写了一个window service去监视Tas ...
- window service 创建
1:vs中创建一个 window servece 2.右键 添加安装程序 3.更改属性视图中的Account属性为LocalService(本地服务) 更改ServiceName为你自己的服务名称 ...
- streambase service 变为 window service启动
1.配置出.sbdeploy文件 2.安装streambase服务 streambase command line :--install-service 即可安装对应的的window service ...
- 【Window Service】关于Window Service的两三事
引言 Window Service通常用于寄宿WCF服务或者定时作业.下面记录一下它的用法. 创建 创建Window Service项目后,可以看到Program和Service1类.Program ...
- C# Window Service安装、卸载、恢复选项操作
using System;using System.Diagnostics;using System.Linq;using System.ServiceProcess; namespace ScmWr ...
随机推荐
- 常见NoSQL的CAP归类
关注一致性和可用性的 (CA) 这些数据库对于分区容忍性方面比较不感冒,主要采用复制(Replication)这种方式来保证数据的安全性,常见的CA系统有:1. 传统关系型数据库,比如Postgres ...
- WebAPI Token 验证
WebAPI Token 验证 登录端 //HttpContext.Current.Session.Timeout = 10; ////生成Ticket //FormsAuthenticationTi ...
- JQuery 的一个轻量级 Guid 字符串拓展插件.
(function ($) { function guid(g) { var arr = new Array(); //存放32位数值的数组 if (typeof (g) == "strin ...
- CryptoJS与C#AES加解密互转
CryptoJS下载地址: https://code.google.com/archive/p/crypto-js/downloads http://download.csdn.net/detail/ ...
- 使用nexus来搭建Nuget私服
近期在搭建nuget私服.选择nexus这个产品.nexus支持npm,.nuget等,功能比较强大. 前言 博主使用centos7.5来搭建nexus,遇到了不少的问题.最后还是搞定了. 1:下载n ...
- 双缓冲队列解决WPF界面卡死
工作中的项目,CS客户端会通过MQ接收前端设备发送的信息,之前测试的时候,由于测试的数据不大,没有进行压力测试,软件可以正常工作,随着项目现场设备数量的增加,CS客户端从MQ中订阅的数据量不断增加,最 ...
- 适合新手看的ref和out
面试的时候一般很高的概率会问到ref和out的区别...我们死记硬背的话很难记住. 建议大家和我一样简单的探索一下.动手试一下就能记住了. 共同点是我们在使用ref或者out的时候一定要在写的方法里面 ...
- ODP.NET 之 ExecuteNoQuery 执行 Merge into 返回值
当执行Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteNonQuery时,如果sql语句是 merge into ...,则返回值表现不稳定, ...
- 前端工具Rythem介绍
Rythem是一个与Fiddler同类的软件,和Fiddler一样具有 代理抓包/替换 功能,与Fiddler最大的不同是Rythem是跨平台&开源的. 另外,根据笔者的一次开发经验,Ryth ...
- Mybatis常用知识点总结
1. #{}和${}的区别是什么? ${}是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替换,比如${driver}会被静态替换为com.mysql.jdbc ...