封装RabbitMQ.NET Library 的一点经验总结 转载

这篇文章内容会很短,主要是想给你们分享下我最近在作一个简单的rabbitmq客户端类库的封装的经验总结,说是简单其实一点都不简单。为了节省时间我主要按照Library的执行顺序来介绍,在你看来这里仅仅是一个简单的经验总结,可是在我看来这些经验只有在你真正的封装rabbitmq客户端库的时候且将你的客户端安全稳定的发布上线后才会真的发现这些问题。html

好比你的库只是连接单个Node的时候和连接高可用集群的HAProxy时候是彻底两回事。当你未能在你的库里使用反向注入LOG接口的时候一旦在线上发生网络解析和序列化等一系列在线问题时候你是多么无能为力。当你使用同步循环获取队列消息的时候一旦发生异常你的连接就会断掉等等这些细节。我总结了我在编写这个library的时候慢慢稳定下来的过程和经验。至少目前来看网络上的文章,固然我是指.NET/C#方面的,都没有讲到这些问题,大部分的文章都是简单的介绍了一个最最基本的使用和最最基本的demo而已,达不到企业级使用的要求。在这个过程当中,感谢个人团队和给过我指导的同事,让我明白了一些技术道理。git

好东西不能石沉大海,尤为是.NET领域更须要这样的东西来填补这一空缺。废话很少说了,进入主题,那些编写框架和组件的大道理这里就不讲了,我只说重点。github

1.发送连接、通道和接受连接、通道要关注点分离

就是说你的接受Channel和发送的Channel要分离开,若是不分开会出现偶发性的消息串掉的错误,我这里如今没有环境没法重现截图。我是在作压力测试的时候,用了一个Channel的时候Debug抛出来的异常。若是你有洁癖建议把IConnection也分离开。这样不容易出错,就算出错排错也会很容易。安全

(图1:分开接受和发送的IConnection、Channel)服务器

还有一点,不要将这些对象直接散落在直接使用的Client类中,要创建起一个使用上下文,就算你暴露在外面的是一个具体的类可是那个类也是一个空壳子。网络

2.客户端发送消息的时候要标记上消息的持久化状态

咱们能够在建立队列的时候设置此队列是持久化的,可是队列中的消息要在咱们发送某个消息的时候打上须要持久化的状态标记。多线程

(图2:标记此消息是须要持久化的)架构

3.要在监听的线程入口后加try{}catch{}

(图1:在线程内部方法中加try{}catch{})框架

这个点不少作封装的人会容易忽视掉,我这里补充下为了保持这个文章的完整性。测试

其实在我以前的“.NET应用架构设计—服务端开发多线程使用小结(多线程使用常识)”一文中有讲到过。

这个时候你的try{}catch{}实际上是不会捕获到任何ListenInit方法中的异常的,由于他在另一个线程上下文中执行的。具体原理这里就不解释了。可是能够很容易的理解就是,你这个方法一旦执行就会立马返回了。

4. 初始化的监听链接的时候要订阅Shutdown事件记录下LOG

(图4:监听Shutdown事件,记录下LOG便于排查和监管服务的稳定性)

5. 要在内部定义一个LOG反向注入接口

(图5:组件内部的LOG接口)

此接口就是你内部用来将信息传输出去的渠道,并且这个渠道是活的,有各个应用系统决定怎么记录。

简单处理你还须要一个LOG接口服务定位器对象,要否则你拿不到这个接口实例。

(图6:LOG location对象)

6. 千万不要使用while(true)接受消息

若是咱们是使用死循环的方式在接受消息,那么一旦当你的接受消息的程序出现异常那么你的while直接就会跳出,你的连接多是还连接在服务器上可是你的channel已经断开,说白了你的消息是不会接受到的,并且这样的开发方法很不稳定也不优雅。咱们可使用面向事件的消费者来接受消息。

(图7:使用Eventing类型的消费者接受消息)

7.设置一次只接受一个消息,而不是直接LOCK住全部的队列消息

默认状况下,一个队列里无论多少消息当你一个TCP链接打上去以后会LOCK住全部的消息,也就是说一个链接完全占用了全部的消息,此时消息不会被其余集群的机器消费。

(图8:一次只取一个消息进行消费)

可是若是你对消息的处理的先后顺序有要求就不能这么作,你须要独立注册一个队列,而后将这样的一此只消费一个消息配置话。

8.自动从新链接,不须要手动处理自动链接

(图9:建立出一个会自动重连的Connection对象)

9.心跳超时时间(集群、高可用部署时相当重要的设置)

(图10:设置心跳超时时间)

若是你链接单台节点的时候不设置这个值是没问题的,可是若是你链接的是相似HAProxy虚拟节点的时候就会出现TCP被断开的可能性。若是你不设置这个心跳超时时间,它默认是不进行心跳保持的,就会出现网络中的某个设置断开空闲的TCP链接资源。就这个问题一直搞的咱们的团队到次日两点钟。你们要记住这个点。

10.消费失败的消息要从新放入队列

(图11:从新放入队列,推送给其余消费着)

总结:

最后,我是基于Rabbitmq.Client 版本3.5.3.0的基础上开发的,这个你们要注意。版本不同会有必定的差别性。但愿此文对你们在使用rabbitmq的同志有一点帮助,谢谢。

github地址:https://github.com/Plen-wang/rabbitmqclient

 

原文地址:https://www.cnblogs.com/wangiqngpei557/archive/2015/08/22/4751124.html

相关文章
相关标签/搜索