在.NET上使用ZeroMQ
前言
最近在设计一个Web系统(公司在建项目,故保密不能详述),要满足高并发,高访问量、高可靠性的需求,又会涉及到多种业务外部系统,甚至业务可能是可“热插拔”的形式,同时又要最求成本最低。
考虑到总总因素,排除了使用Oracle数据库,以及其他各种商业组件的方案;同时又由于公司项目很多,缺乏人手来自己开发一些组件,故除了业务系统是自己开发外,其他基本上采用了清一色的开源软件。 由于业务比较复杂,同时大量使用了各种开源系统,会使用到C++, Java, Erlang, C#, PHP等众多语言。故设计用系统总线(Bus)来作为消息的介质,协调整体的运行,而这条总线的性能和特性也将关系到系统的命运。
RabbitMQ or ZeroMQ?
经过比较选型,从多语言的支持的角度,最后筛选得到RabbitMQ和ZeroMQ两个选择。
RabbitMQ是采用Erlang开发的,支持完善的AMQP协议;ZeroMQ使用C语言开发,重点在于效率;两者均有多语言支持,其中ZeroMQ支持得较多。
比较看, RabbitMQ支持的AMQP协议,较为完整和复杂;而ZeroMQ的接口极为简单。速度上,还未对亲自对两者做压力测试。从网上的资料看,RabbitMQ较慢,几十个并发以内,延时为几十毫秒,但当客户端达到1000个并发的时候,速度就无法容忍了(参考);ZeroMQ上则据称可以达到13毫米延时和高达每秒4.1兆次传递(参考, 国内需要翻墙才能访问)。如果队列较多的话,RabbitMQ很容易把内存耗尽,而ZeroMQ则把队列内容保存在发送端。
故最终还是决定选择了ZeroMQ,然后在上面加一层我自己的封装,作为Web系统的消息总线。
在.NET上使用ZeroMQ
ZeroMQ的.NET封装很简单,基本上是来自C-API的,但有所简化。使用上,由于习惯了在C#里面用强类型约束,API上的int类型让我感觉封装得"非常不.NET"。
首先要明确下ZeroMQ的几个概念: