ZeroMQ指南-第1章-基础-我们为何需要ØMQ

我们为何需要ØMQ

现在你已经见识了ØMQ的实际应用,让我们回到“为什么”。

目前很多应用程序由跨越某种网络的组件组成,不是局域网就是互联网。那么多的程序员最终都在从事某种消息传递。一些开发者使用消息队列产品,但大多是用TCP或UDP来自己开发。这些协议不难使用,但是从A到B发送少量字节和任何可靠方式的消息传递之间是有非常大的区别的。

让我们看看当我们开始用原始TCP来连接时面临的典型问题。任何可重用的消息层都需要解决全部或大部分以下问题:

  • 我们如何处理I/O?你的程序阻塞吗,还是在后台处理I/O?这是设计上的一个关键。阻塞I/O创建的架构不能很好扩展。但是后台I/O要做好是非常困难的。
  • 我们如何处理动态组件,就是会暂时离开的部分?我们是否要在形式上将组件划分为“客户端”和“服务器”,并要求服务器不能消失?那如果我们想要服务器连接服务器怎么办?我们是否要每隔几秒就尝试重新连接?
  • 我们如何表述线上的消息?我们如何将数据组帧才能让它易写易读,缓冲溢出也很安全,对小型消息也很高效,又能够胜任关于戴着狂欢帽的跳舞猫的超大视频?
  • 无法立刻投递的消息我们又如何处理?尤其是正当我们等着一个组件回到在线状态?我们是放弃消息,扔到数据库里,还是放到一个内存队列中?
  • 我们把消息队列存到哪儿去?如果组件从队列读取的速度很慢导致队列堆积是什么原因?这种情况下我们的对策又是什么?
  • 丢失的消息我们如何处理?我们是等待新数据,请求重发,还是建造某种可靠性层来保证消息无法丢失?那如果这个层自身崩溃了又怎么办?
  • 假设我们要使用不同的网络传输会如何。比如说,用多播来替代TCP单播?或者IPv6?我们需要重写程序吗,或者传输已经抽象到某个层了吗?
  • 我们如何路由消息?我们能将同一消息发送到多个对等点吗?
  • 我们如何写一个用于其它语言的API?我们是重新实现一个线路级协议还是重新打包一个库?如果是前者,如何保证效率和稳定堆叠?如果是后者,如何保证互用性?
  • 我们如何表述数据让它能在不同架构间读取?我们要对数据类型强制一种特定编码吗?这是消息系统的工作吗,难道不该是更高层的事吗?
  • 如何处理网络错误?我们是等待重试,悄然忽略,还是中断?

看一个典型的开源项目如HadoopZookeeper,参见src/c/src/zookeeper.c里的C API。当此文写作时,2010年,已有3200行神秘代码,里面有个未公开的客户端服务器网络通信协议。我明白它很有效率因为使用了poll()而不是select()。但实际上,Zookeeper应该使用一个通用的消息层和显式公开的线路级协议。对于团队来说要一遍一遍的建造这个独特的轮子真是个惊人的浪费。

但是如何制作可重用消息层?为何当那么多项目需要这项技术,人们还是在用困难的办法,通过在代码中驱使TCP套接字,并解决着那个长长列表中的难题,一遍一遍?

图7 – 开始时的消息传递Messaging as it Starts

事实证明建造可重用消息传递系统真的很难,这就是为何只有少数FOSS(自由开源软件)尝试过,而商业的消息传递产品为何复杂、昂贵、僵化、脆弱。2006年iMatix公司设计了AMQP(高级消息队列协议),它开始给予FOSS开发者或许是第一个消息传递系统的可重用处方。AMQP比很多其它设计都工作的更好,但还是相对复杂、昂贵、脆弱。需要花数周时间来学习使用,数月时间才能创造出当事情变得复杂时不至于崩溃的稳定架构。

大部分消息传递项目,例如AMQP,在尝试以可重用方式解决这个长列表中的难题时,是通过发明一个新概念,“中介”,来做寻址、路由、和队列。这导致了一个客户端服务器协议或者一组API构建在一些未公开协议之上,来让程序与中介交谈。中介在减少大型网络复杂度方面是非常出色的。但是将基于中介的消息传递添加到产品例如Zookeeper将使它更糟,而不是更好。这将意味着添加一个额外的大型机,和一个新的单一故障点。中介迅速的成为一个瓶颈和一个新的管理风险。如果软件支持,我们能添加第二、第三、第四个中介,还能做一些容错方案。人们这么做着。创建了更多的移动部件、更多复杂度、更多故障。

并且以中介为中心的模式需要它自己的操作团队。你真的需要日夜观察着中介,当它行为不当时用棍子抽打。你需要机子,还需要备份的机子,还有管理这些机子的人。只有在做有很多移动部件、多个团队人员建造的、跨越多年的大型程序时才值得这么做。

所以中小型程序开发者被困住了。要么他们避免网络编程,去做无需缩放的整体应用。要么他们跳入网络编程去做脆弱、难以维护的复杂程序。要么他们下赌注在一个消息传递产品上,最终可扩展性程序基于昂贵、易碎的技术。真没有什么好的选择,这也许是为何消息传递在上世纪死死卡住并激起强烈情绪。对于用户来说是负面的,对于依靠支持和授权来盈利的人则是兴奋而愉悦的。

图 8 – 消息传递变成了Messaging as it Becomes

我们需要的是能做消息传递但方式上如此简单而廉价,它能够以接近零的成本,工作在任何程序中。它应该是一个只需要链接的函数库,无需任何其它依赖。没有附加的移动部件,所以也没有附加的风险。应当能运行在任何操作系统和任何编程语言。

而这就是ØMQ:一个高效的、可嵌入库,解决了让一个程序变得富有弹性的跨过网络的大部分难题,成本不高。

特别是:

  • 它在后台线程异步的处理I/O。这些后台线程使用无锁数据结构与程序线程交流,所以并发ØMQ程序不需要锁、信号量、或其它等待状态。
  • 组件可以动态的来来去去,而ØMQ会自动重连。这意味着你可以按任意顺序启动组件。你可以创建“面向服务架构”(SOAs),服务可以随时加入和离开网络。
  • 当需要时它自动将消息排入队列。以智能的方式,消息排入队列前推送消息到尽可能靠近接收者。
  • 它有几种办法处理满溢队列(称为“高水位线”)。当队列填满时,ØMQ自动阻塞发送者,或丢弃消息,取决于你用的消息传递方式(所谓的“模式”)。
  • 它让你的程序用任意传输方式来相互交谈:TCP、多播、进程内、进程间。更改传输方式时无需更改代码。
  • 安全处理低速/阻塞的读者,使用的是取决于消息传递模式的不同策略。
  • 它让你路由消息使用各种模式如请求-应答和发布-订阅。这些模式是你创建拓扑、网络结构的方式。
  • 它让你用一个调用就能创建代理来做队列、转发、或捕获消息。代理可以降低网络的互联复杂度。
  • 它使用简单的线上组帧,转发整个消息并精确重现其发送时的样子。如果你写入一个10K的消息,就能接收一个10K的消息。
  • 它不在消息上强加任何格式。消息就是零到千兆大小的二进制大对象。想要描述数据时你可以在其上选择一些其它产品,例如谷歌的协议缓冲(protocol buffers)、外部数据表示法(XDR)、或其它。
  • 它智能的处理网络错误。有时它会重试,有时它告知你一个操作失败了。
  • 它减少你的碳排放。用更低的CPU消耗做更多事意味着你的机子使用了更少的能源,并且可以让你的旧机器使用的更久。阿尔·戈尔会很喜欢ØMQ。

事实上ØMQ做的比这更多。对于如何开发支持网络的程序方面具有颠覆性效果。表面上它是一个受到套接字启发的API,你通过它做zmq_msg_recv()和zmq_msg_send()。但消息处理很快变成了中心循环,而你的程序马上分解成一组消息处理任务。优雅而自然。并扩展着:每个任务映射到一个节点,节点们通过任意传输方式相互交谈。进程内的两个节点(节点是线程),机子上的两个节点(节点是进程),或网络上的两台机子(节点是机子)——都是一样的,程序代码没有变化。

套接字扩展性

我们再看看ØMQ的扩展性。这里是一个shell脚本用于启动天气服务器然后启动一群并行的客户端:

wuserver &
wuclient 12345 &
wuclient 23456 &
wuclient 34567 &
wuclient 45678 &
wuclient 56789 &

客户端运行时,我们用“top”命令来看看活动进程,会看到类似于(在4核机子上):

 PID  USER      PR  NI VIRT  RES  SHR  S %CPU %MEM     TIME+ COMMAND
 7136 ph        20   0 1040m 959m 1156 R  157 12.0  16:25.47 wuserver
 7966 ph        20   0 98608 1804 1372 S   33  0.0   0:03.94 wuclient
 7963 ph        20   0 33116 1748 1372 S   14  0.0   0:00.76 wuclient
 7965 ph        20   0 33116 1784 1372 S    6  0.0   0:00.47 wuclient
 7964 ph        20   0 33116 1788 1372 S    5  0.0   0:00.25 wuclient
 7967 ph        20   0 33072 1740 1372 S    5  0.0   0:00.35 wuclient

让我们想想看这发生了什么。天气服务器有一个单独的套接字,我们让它向五个并行客户端发送数据。我们可能会有成千上万的并发客户端。服务器程序看不到它们也不会直接与它们交谈。那么ØMQ就像个小服务器,默默接受客户端请求并以网络能处理的最快速度将数据推出。而且它是个多线程服务器,从你的CPU中榨取更多的汁水。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ZeroMQ—指导 由iMatix公司的首席执行官Pieter Hintjens 编写。感谢Bill Desmarais, Brian Dorsey, CAF, Daniel Lin, Eric Desgranges, Gonzalo Diethelm, Guido Goldstein, Hunter Ford, Kamil Shakirov, Martin Sustrik, Mike Castleman, Naveen Chawla, Nicola Peduzzi, Oliver Smith, Olivier Chamoux, Peter Alexander, Pierre Rouleau, Randy Dryburgh, John Unwin, Alex Thomas, rofl0r, Mihail Minkov, Jeremy Avnet, Michael Compton, and Zed Shaw的贡献,也感谢Stathis Sideris,因为Ditaa.。 请对所有的意见和勘误表进行问题跟踪。这个版本覆盖了0MQ2.0的版本,发表于周二2010年11月9日,9时32分19秒。 第一——基础的东西 修理(fixing)这个世界 怎么解释0MQ?有些人会说它的所有美好的事情。它是类固醇(steroids)上的套接字。它像有路由的邮箱。它很快。别人想分享它的启蒙,当这一切变得越来越明显,人们开始顿悟了。事情变得更简单。再也不复杂了。它打开了人们的思维。其他人喜欢通过做比较的方式来解释。它更小,更简单,但是看起来仍然很熟悉。就我个人而言,我希望回忆起我们为什么要开发0MQ,因为,这是读者们也很想知道的问题。 编程是装扮成艺术的科学,因为我们中的大多数不了解软件的物理过程。如果学过这方面的知识的话,也学的很少。软件的物理过程不是算法,数据结构,语言和抽象。这些只是我们研发,使用,然后扔掉的工具。软件真正的物理过程实际上是人们的思维过程。 ……
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值