以前的文章中,介绍了如何将RabbitMQ以WCF方式进行发布。今天就介绍一下咱们产品中如何使用RabbitMQ的!
在Discuz!NT企业版中,提供了对HTTP错误日志的记录功能,这一点对企业版很是重要,另外存储错误日志使用了MongoDB,理由很简单,MongoDB的添加操做飞快,即便数量过亿以后插入速度依旧不减。
在开始正文以前,先说明一下本文的代码分析顺序,即:程序入口==》RabbitMQ客户端===>RabbitMQ服务端。好了,闲话少说,开始正文!
首先是程序入口,也就是WCF+RabbitMQ客户端实现:
由于Discuz!NT使用了HttpModule方式来接管HTTP连接请求,而在.NET的HttpModule模板中,能够经过以下方法来接管程序运行时发生的ERROR,以下:
html
而“记录错误日志"的功能入口就在这里:
java
固然从代码能够看出,记录日志的工做基本是经过配置文件控制的,即“HttpModuleErrLog.Enable”。
而RabbitMQClientHelper是一个封装类,主要用于反射生成IHttpModuleErrlogClient接口实例,该实例就是“基于WCF发布的RabbitMQ”的客户端访问对象。
mongodb
能够看出它反射的是Discuz.EntLib.RabbitMQ.dll文件的HttpModuleErrLogClient对象(注:使用反射的缘由主要是解决企业版代码与广泛版代码在项目引用上的相互依赖),下面就是其接口和具体要求实现:
数据库
能够看出,AddLog方法与上一篇中的客户端内容基本上没什么太大差异,只不过它提供了同步和异步访问两种方式,这样作的目的主要是用户可根据生产环境来灵活配置。
下面就来看一下RabbitMQ的服务端实现,首先看一下其运行效果,以下图:
接着看一下启动rabbitmq服务的代码:
app
上面代码会添加IHttpModuleErrLogService接口实现类HttpModuleErrLogService 的Endpoint,并启动它,下面就是该接口声明:
异步
代码很简单,就是定义了一个添加日志的方法:void AddLog(HttpModuleErrLogData httpModuleErrLogData)
下面就是接口的具体实现,首先是类声明及初始化代码:
ui
能够看出,这里使用了静态定时器对象,来进行定时访问队列信息功能(“非同步出队”操做),这样设计的缘由主要是为用户提供适合的配置方式,即若是不使用定时器(为0时),则系统会在日志入队后,就当即启动出队(“同步出队”)操做获取日志信息并插入到MongoDB数据库中。
下面介绍一下入队操做实现:
spa
代码很简单,主要构造rabbitmq连接(ConnectionFactory)并初始化相应参数如用户名,密码,ROUTING_KEY等。
而后将传入的日志对象序列化成字符串对象,赋值给targetBody["body"],这样作主要是由于我没找到更好的方法来赋值(以前尝试直接绑定httpModuleErrLogData到targetBody["body"],但在出队操做中找不到合适方法将httpModuleErrLogData对象解析出来)。
下面就是出队操做:
设计
出队操做也是先实例化连接到rabbitmq 的实例,并循环使用BasicGet方法来单条获取队列信息,并最终将res.Body的数据序列化成HttpModuleErrLogData对象,并最终插入到mongodb数据库中。同时将获取的队列消息显示出来:
3d
这里使用异步方式显示出队的日志信息,其声明的delegate 方法“ShowMsg”以下:
同时使用LoadAttachment方法来实现HttpModuleErrLogData到mongodb的Document类型的转换:
到这里,主要的功能介绍就差很少了。固然本文所阐述的只是一个原型,相信会随着对rabbitmq的理解深刻而不断完善,感兴趣的朋友欢迎讨论交流,以纠正我认识上的误差,呵呵。