分布式系统之分布式中间件zeroMQ

zeroMQ,又称0MQ,是一个非常简单的通信库,它扩展了传统BSD socket能力,提供简单的基于消息的通信。zeroMQ不解析消息体,没有序列化能力,或者说你可以使用任何第三方序列化库比如google的protocol buffer。

 

iMatix公司,AMQP协议的制定者,在2010年退出了AMQP工作组,其CEO Pieter Hintjens 认为AMQP从根本上就有不可修改的缺陷,太复杂了,目前转而支持zeroMQ,iMatix 2011年后不再维护其AMQP软件OpenAMQP。

 

在zeroMQ的guide中,将现在(将来)的软件类比人类的大脑,几万亿个神经元互相之间发送消息来完成一些任务,没有控制点,没有单点故障。而现实中,软件和软件间的互联极难,非常难以维护和控制。IETF已经建立了很多标准,用来解决这个问题,HTTP是一个非常简单的解决方案,但是这个解决方案让问题更加复杂:HTTP鼓励开发者和架构师将软件设计为复杂、万能的中心服务器和简陋、愚蠢的客户端。这造成了现在整个互联网到处是中心点,难以控制,即使有分布式的P2P架构(skype,bittorrent),也只是些玩具,很少有人使用它们来传输数据,解决实际生产问题。

 

OK,实践实践。按照guide上的说明,下面使用zeroMQ做一个简单的helloworld分布式程序。

首先安装zeroMQ,从网站上下载当前release版本,然后编译安装,需要g++和uuid-dev(在俺的亚马逊ec2虚拟机上没有,现yum安装,汗。。。)。编译出来的动静态库和头文件默认都放到了/usr/local目录下的lib和include目录下。

 

server代码:

#include <zmq.h>
#include <stdio.h>
#include <string.h>

int main()
{
    void *context = zmq_init(1);

    void *s = zmq_socket(context, ZMQ_REP);
    zmq_bind(s, "tcp://*:5555");

    while (1)
    {
        zmq_msg_t msg;
        zmq_msg_init(&msg);
        zmq_recv(s, &msg, 0);
        printf("received hello\n");

        zmq_msg_close(&msg);

        zmq_msg_init_size(&msg, 5);
        memcpy(zmq_msg_data(&msg), "World", 5);
        zmq_send(s, &msg, 0);
        zmq_msg_close(&msg);
    }

    zmq_close(s);
    zmq_term(context);
}

 

client代码:

#include <stdio.h>
#include <string.h>
#include <zmq.h>

int main()
{
    void *ctx = zmq_init(1);
    void *s = zmq_socket(ctx, ZMQ_REQ);
    zmq_msg_t msg;
    char buf[10];

    zmq_connect(s, "tcp://localhost:5555");

    zmq_msg_init_size(&msg, 5);
    memcpy(zmq_msg_data(&msg), "hello", 5);
    zmq_send(s, &msg, 0);
    zmq_msg_close(&msg);

    zmq_msg_init(&msg);
    zmq_recv(s, &msg, 0);
    memcpy(buf, zmq_msg_data(&msg), 5);
    buf[5] = 0;
    printf("%s\n", buf);

    zmq_msg_close(&msg);
    zmq_close(s);
    zmq_term(ctx);
    return 0;
}

 

Makefile:

all: server client
server: server.c
    gcc -o $@ $< -lzmq
client: client.c
    gcc -o $@ $< -lzmq

 

ok,测试通过。解释一下,客户端和服务端都是首先初始化一个zmq的context,然后创建一个socket,客户端创建request类型的,服务端创建reply类型的,服务端bind一个地址,客户端connect这个地址,然后客户端发送一个消息,服务端收到后回应一个消息。

 

可以看到如下几点:

0. zeroMQ就是一个通信库,提供创建socket,建立连接,监听端口,发送消息,接收消息的功能。

1. 使用类似URL的字符串方式指定一个地址,远远比BSD socket的sockaddr好用。

2. context创建时可以指定有多少个I/O线程,可以并发进行多个线程处理

3. 对于string,不假定有'\0'结束符,便于多种语言进行交互

4. 对于消息内容,zeroMQ不做任何解析,就是一段长度的字节流,编解码由客户端和服务端自己搞定

5. 最后很有趣的一点,先启动客户端,再启动服务端,程序照样运行正常,说明在建立连接时,如果被连接的服务端不存在,客户端会等待并尝试重连。这一点对分布式系统的容错性比较有意义。

 

先到这里,后续深入分析。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值