原文链接 http://www.aosabook.org/en/zeromq.html
ZeroMQ
ZeroMQ 是一个消息系统,或者‘面向消息的中间件’。广泛应用于金融服务,游戏开发,嵌入式系统,学术研究和航空航天领域。
消息系统基本上用于应用程序的即时消息传递,应用程序决定将事件传递给另一个应用程序(或多个应用程序),将要发送的数据组装,点击‘发送’按钮,然后消息系统来处理剩余的问题
与及时消息不同,消息系统没有GUI,假定在端点出现故障时没有人进行智能干预。因此,消息系统必须是容错的,而且比普通的及时消息要快的多 。
ZeroMQ最初被构想为股票交易中的超快速消息传递系统,所以重点是极端优化。该项目第一年是设计基准方法,试图定义尽可能高效的体系结构。
后来,大概是在第二年,重点转移到提供一个通用的系统,用于构建分布式应用程序和支持任意消息传递模式,多种传输机制,任意语言绑定等
在第三年,重点是提高可用性和扁平化学习曲线。我们采用了BSD套接字API,试图清理个人消息模式的语义等等。
希望本章能洞察以上三个目标是如何转化为ZeroMQ的架构的,并为那些正在解决同样问题的人提供一些建议。
应用和库
Zero是有一个库,不是一个消息服务器。
我们的主要关注点是性能:如果中间有一个服务器,每条消息将两次通过网络(发送者到代理,代理到接收者),包括延迟和吞吐量的损失。如果所有的消息都必须通过代理,在某些时候,一定会成为瓶颈。
其次是关于大规模部署:当部署跨越组织边界时,管理整个消息流的中心管理概念就不再适用。任何公司都不愿意将控制权让与其他公司的服务器;有商业秘密,也有法律责任。实际的结果是,每个公司都有一个消息服务器,用手写的网桥连接其他公司的消息系统。整个生态系统因此四分五裂,为每一家相关公司维护大量桥梁并不能使情况好转。为了解决这个问题,我们需要一个完全分布式的体系结构,即每个组件都可能由不同的业务实体管理。考虑到基于服务器的体系结构中的管理单元是服务器,我们可以通过为每个组件安装一个单独的服务器来解决这个问题。在这种情况下,我们可以通过使服务器和组件共享相同的流程来进一步优化设计。我们最终得到的是一个消息传递库。
当我们知道如何在没有中央服务器的情况下进行消息传递时,MQ就开始了。从一开始,MQ就是一个库,而不是一个应用程序。
经验教训是,当启动一个新项目时,如果可能的话,您应该选择库设计。从一个库中通过一个简单的程序调用它很容易,但是,从一个现有的可执行文件中创建一个库几乎是不可能的。库为用户提供了更大的灵活性,同时也为他们节省了不必要的管理工作。
全局状态
全局变量在库中不能很好地发挥作用。一个库可能在这个过程中加载好几次,但即使如此,也只有一组全局变量。下图显示了从两个不同和独立的库中使用的ZeroMQ库。然后应用程序使用这两个库。
当出现这种情况时,这两个实例都会访问相同的变量,从而导致竞争条件、奇怪的失败和未定义的行为。
为了防止这个问题,ZeroMQ库没有全局变量。相反,库的使用者负责显式地创建全局状态。包含全局状态的对象称为上下文。虽然从用户的角度来看,上下文看起来类似于一个工作线程池,但从MQ的角度来看,它只是一个对象,用来存储我们碰巧需要的任何全局状态。在上面的图片中,libA和libB都有自己的上下文。
这里的经验很明显:不要在库中使用全局状态。如果您这样做了,那么在同一进程中实例化两次库时,它可能会异常。