正德工坊

使用ZMQ开发高性能分布式应用

   定义高性能,这里指的是高流量、低延时。在服务器端,大量的消息蜂拥而至,每个消息都需要“马上”应答,需要服务器能够提供足够的处理能力。
   其实也考虑过其他的方案,broker化的如ActiveMQ以及自己写Socket。ActiveMQ的确方便,但是消息一大Latency马上就飙升,功能太多也感觉累赘。不过有朋友要做性能不是太敏感的服务我还是会推荐这个,开发快学习周期短。自己写Socket写出来简单,写好太难,没办法保证高流量的可靠性和稳定性(也许有同学可以,我水平还差了点)。
   ZMQ相对而言不能说它是最快的,但目前来说它是大流量下延时变长相对不明显的,基本能保证大流量下速度的稳定性。
   简单介绍一下,ZMQ(www.zeromq.org)是一个开源的网络中间件,个人感觉用来代替原生的Socket非常好用。ZMQ的主要元素包括Context、Socket(zmq socket)、Message(zmq message)。Z是Zero、零拷贝的意思。ZMQ封装了底层的连接/重连/封包等。ZMQ支持inter-thread/ipc/tcp传输等。
   由于零拷贝,ZMQ的表现相当不错。在Linux下每个消息大小为几个kb时,每个ipc点对点的消息传输延时大约40us,机器对机器的tcp消息传输延时大约200us。ZMQ自带测试用的代码,有兴趣的同学可以详细测试一下。
   与Poll和timerfd结合起来,可以构建无等待的消息处理循环。这里的无等待是指没有额外的等待,消息的传入还是需要poll的。
 1 int main()
 2 {
 3         int tfd, rc ;
 5         tfd = timerfd_init();
 6 
 7         context_t *cxt = new context_t(1);
 8         socket_t *socket = new socket_t(*cxt,ZMQ_SUB);
 9         socket->connect("tcp://127.0.0.1:5000");
10         socket->setsockopt(ZMQ_IDENTITY, "Hello", 5);
11         socket->setsockopt(ZMQ_SUBSCRIBE, "", 0);
12 
13         pollitem_t *items = new pollitem_t[2];
14 
15         items[0] = pollitem_t{NULL, tfd, ZMQ_POLLIN, 0};
16         items[1] = pollitem_t{*socket, 0, ZMQ_POLLIN, 0};
17 
18         while(1)
19         {
20                 rc = zmq::poll (items, 2, _interval);
22                 if (items [0].revents & ZMQ_POLLIN)
23                {
24                         readtimerfd(tfd);
27                 }
28                 if(items[1].revents & ZMQ_POLLIN)
29                 {
30                         message_t msg(0);
31                         socket->recv(&msg,0);
32                         … …
33                 }
34         }
35 }
36 

   使用这样的处理过程构造的典型的双机热备服务器应用,基本能达到流量20~30万/s、典型延时700~800us的程度。当然,这个数字是空转的数字,加上应用的话流量应该有所降低。

posted on 2012-02-18 00:11 AndersLane 阅读(3436) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


My Links

Blog Stats

常用链接

留言簿

随笔分类

文章档案

搜索

最新评论