ZeroMQ指南-第1章-基础-从ØMQ/2.2升级到ØMQ/3.2 标签: zeromqzeroMQZeroMQZMQzmq 2013-02-19 14:50
从ØMQ/2.2升级到ØMQ/3.2
可兼容变化
这些变化并不直接影响现有程序代码:
- 发布-订阅的过滤现已不再位于订阅者端而是位于发布者端。这显著改善了很多发布-订阅用例的性能。
- ØMQ/3.2有很多新的API方法(zmq_disconnect(),zmq_unbind(),zmq_monitor(),zmq_ctx_set(),等等)。
不可兼容变化
这些是对程序和语言绑定有影响的主要领域:
- 改变了发送/接收方法:zmq_send()和zmq_recv()有了不同的更简单的接口,而旧的功能现在由zmq_msg_send()和zmq_msg_recv()来提供。症状:编译错误。方案:修正你的代码。
- 这两个方法成功时返回正数,错误时返回-1。在2.x版本中它们成功时总是返回0。症状:工作的很正常时却表现出错误。方案:严格测试返回值等于-1,而不是非零。
- zmq_poll()现在会等待几毫秒,而不是几微妙。症状:程序停止响应(其实是响应慢了1000倍)。方案:在所有zmq_poll调用中使用下文定义的ZMQ_POLL_MSEC宏。
- ZMQ_NOBLOCK现在叫做ZMQ_DONTWAIT。症状:编译失败于ZMQ_NOBLOCK宏。
- ZMQ_HWM选项现在分解为ZMQ_SNDHWM和ZMQ_RCVHWM。症状:编译失败于ZMQ_HWM宏。
- 多数而非全部的zmq_getsockopt()选项现在是整形值。症状:运行时zmq_setsockopt和zmq_getsockopt返回错误。
- ZMQ_SWAP选项已被移除。症状:编译失败于ZMQ_SWAP。方案:重新设计使用此功能的代码。
推荐的填缝宏
对于希望同时运行于2.x和3.2的程序,例如语言绑定,我们的建议是尽可能的模拟3.2。这里是C的宏定义,用于帮助你的C/C++代码工作于两个版本(来源于CZMQ):
#ifndef ZMQ_DONTWAIT # define ZMQ_DONTWAIT ZMQ_NOBLOCK #endif #if ZMQ_VERSION_MAJOR == 2 # define zmq_msg_send(msg,sock,opt) zmq_send (sock, msg, opt) # define zmq_msg_recv(msg,sock,opt) zmq_recv (sock, msg, opt) # define ZMQ_POLL_MSEC 1000 // zmq_poll is usec #elif ZMQ_VERSION_MAJOR == 3 # define ZMQ_POLL_MSEC 1 // zmq_poll is msec #endif
警告-不稳定范式!
传统网络编程是建立在一个普遍假定上,与一个套接字通话的是一个连接,一个对等点。确实存在多播协议但它属于特例。当假定“一个套接字=一个连接”,我们在某方面扩展了架构。我们创建多个逻辑线程,每个线程与一个套接字、一个对等点配合工作。我们在这些线程中放入智能和状态。
在ØMQ宇宙中,套接字是通往小而快后台通信引擎的门廊,自动管理着整套连接。你无法看到、与之协作、打开、关闭或附加状态到这些连接。无论你用的是阻塞发送或接收,或是轮询(poll),你能通话的是套接字而不是它管理的连接。连接是私有的不可见的,这是ØMQ可扩展性的关键。
因为你的代码,与套接字通话,方可处理任意数量的连接去跨越周围的任何网络协议,而无需更改。位于ØMQ中的消息传递模式比起位于你的程序代码中的消息传递模式扩展起来更加省事。
所以这个普遍假定不再适用。你在阅读代码示例时,你的大脑会尝试把它映射到你已知的事。你读到“套接字”然后想“啊,这表示一个通往其它节点的连接”。这是错误的。你读到“线程”然后你的脑子又会想“啊,线程表示通往其它节点的连接”,而你的脑子又错了。
如果你第一次读到这份指南,要意识到等你写ØMQ代码写了一两天(也许是三四天),你可能会困惑,特别是被ØMQ让事情变得如此简单所困惑,你可能会将那个普遍假定强加于ØMQ,而那是不行的。此时你将体验到你的启迪和信任的时刻,那个嚓-乓-轰般恍然大悟的范式转变时刻,那时一切都变得清晰。