RabbitMQ 与 ZeroMQ--解决分布式计算环境中节点之间的消息通信

一、ZeroMQ 的背景介绍

  引用官方的说法: “ZMQ (以下 ZeroMQ 简称 ZMQ)是一个简单好用的传输层,像框架一样的一个 socket library,他使得 Socket 编程更加简单、简洁和性能更高。是一个消息处理队列库,可在多个线程、内核和主机盒之间弹性伸缩。ZMQ 的明确目标是“成为标准网络协议栈的一部分,之后进入 Linux 内核”。现在还未看到它们的成功。但是,它无疑是极具前景的、并且是人们更加需要的“传统”BSD 套接字之上的一层封装。ZMQ 让编写高性能网络应用程序极为简单和有趣。”

  近几年有关”Message Queue”的项目层出不穷,知名的就有十几种,这主要是因为后摩尔定律时代,分布式处理逐渐成为主流,业界需要一套标准来解决分布式计算环境中节点之间的消息通信。几年的竞争下来,Apache 基金会旗下的符合 AMQP/1.0标准的 RabbitMQ 已经得到了广泛的认可,成为领先的 MQ 项目。

  与 RabbitMQ 相比,ZMQ 并不像是一个传统意义上的消息队列服务器,事实上,它也根本不是一个服务器,它更像是一个底层的网络通讯库,在 Socket API 之上做了一层封装,将网络通讯、进程通讯和线程通讯抽象为统一的 API 接口。

  二、ZMQ 是什么?

  阅读了 ZMQ 的 Guide 文档后,我的理解是,这是个类似于 Socket 的一系列接口,他跟 Socket 的区别是:普通的 socket 是端到端的(1:1的关系),而 ZMQ 却是可以N:M 的关系,人们对 BSD 套接字的了解较多的是点对点的连接,点对点连接需要显式地建立连接、销毁连接、选择协议(TCP/UDP)和处理错误等,而 ZMQ 屏蔽了这些细节,让你的网络编程更为简单。ZMQ 用于 node 与 node 间的通信,node 可以是主机或者是进程。

  三、本文的目的

  在集群对外提供服务的过程中,我们有很多的配置,需要根据需要随时更新,那么这个信息如果推动到各个节点?并且保证信息的一致性和可靠性?本文在介绍 ZMQ 基本理论的基础上,试图使用 ZMQ 实现一个配置分发中心。从一个节点,将信息无误的分发到各个服务器节点上,并保证信息正确性和一致性。

  四、ZMQ 的三个基本模型

  ZMQ 提供了三个基本的通信模型,分别是“Request-Reply “,”Publisher-Subscriber“,”Parallel Pipeline”,我们从这三种模式一窥 ZMQ 的究竟

  ZMQ 的 hello world!

  由 Client 发起请求,并等待 Server 回应请求。请求端发送一个简单的 hello,服务端则回应一个 world。请求端和服务端都可以是 1:N 的模型。通常把 1 认为是 Server ,N 认为是 Client 。ZMQ 可以很好的支持路由功能(实现路由功能的组件叫作 Device),把 1:N 扩展为N:M (只需要加入若干路由节点)。如图 1 所示:

  图1:ZMQ 的 Request-Reply 通信

  服务端的 php 程序如下:

<?php
/*
* Hello World server
* Binds REP socket to tcp://*:5555
* Expects "Hello" from client, replies with "World"
* @author Ian Barber &lt;ian (dot) barber (at) gmail (dot) com&gt;
*/
$context = new ZMQContext (1);
// Socket to talk to clients
$responder = new ZMQSocket ($context, ZMQ::SOCKET_REP);
$responder-&gt;bind ("tcp://*:5555");
while(true) {
// Wait for next request from client
$request = $responder-&gt;recv ();
printf ("Received request: [%s]\n", $request);

// Do some 'work'
sleep (1);

// Send reply back to client
$responder-&gt;send ("World");
}

  Client 程序如下:

<?php

/*

* Hello World client

* Connects REQ socket to tcp://localhost:5555

* Sends "Hello" to server, expects "World" back

* @author Ian Barber &lt;ian (dot) barber (at) gmail (dot) com&gt;

*/
$context = new ZMQContext ();

// Socket to talk to server

echo "Connecting to hello world server...\n";

$requester = new ZMQSocket ($context, ZMQ::SOCKET_REQ);

$requester-&gt;connect ("tcp://localhost:5555");

for($request_nbr = 0; $request_nbr != 10; $request_nbr++) {

printf ("Sending request %d...\n", $request_nbr);

$requester-&gt;send ("Hello");

$reply = $requester-&gt;recv ();

printf ("Received reply %d: [%s]\n", $request_nbr, $reply);

}

  从以上的过程,我们可以了解到使用 ZMQ 写基本的程序的方法,需要注意的是:

  a) 服务端和客户端无论谁先启动,效果是相同的,这点不同于 Socket。

  b) 在服务端收到信息以前,程序是阻塞的,会一直等待客户端连接上来。

  c) 服务端收到信息以后,会 send 一个“World”给客户端。值得注意的是一定是 client 连接上来以后,send 消息给 Server,然后 Server 再 rev 然后响应 client,这种一问一答式的。如果 Server 先 send,client 先 rev 是会报错的。

  d) ZMQ 通信通信单元是消息,他除了知道 Bytes 的大小,他并不关心的消息格式。因此,你可以使用任何你觉得好用的数据格式。Xml、Protocol Buffers、Thrift、json 等等。

  e) 虽然可以使用 ZMQ 实现 HTTP 协议,但是,这绝不是他所擅长的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值