【有道结合自己翻译】
本章,我们将亲自动手学习怎么在真实程序用使用这些工具:
包含:
- How to create and work with ZeroMQ sockets.
- How to send and receive messages on sockets.
- How to build your apps around ZeroMQ’s asynchronous I/O model. 如何围绕ZeroMQ的异步I/O模型构建你的应用程序。
- How to handle multiple sockets in one thread.
- How to handle fatal and nonfatal errors properly. 如何正确处理致命和非致命错误
- How to handle interrupt signals like Ctrl-C. 如何处理中断信号,如Ctrl-C
- How to shut down a ZeroMQ application cleanly. 如何干净地关闭ZeroMQ应用程序
- How to check a ZeroMQ application for memory leaks. 内存泄露
- How to send and receive multipart messages.
- How to forward messages across networks. 如何跨网络转发消息
- How to build a simple message queuing broker. 如何构建一个简单的消息队列代理
- How to write multithreaded applications with ZeroMQ.
- How to use ZeroMQ to signal between threads.
- How to use ZeroMQ to coordinate a network of nodes. 如何使用ZeroMQ来协调网络中的节点
- How to create and use message envelopes for pub-sub. 如何为发布-订阅创建和使用消息信封
- Using the HWM (high-water mark) to protect against memory overflows.
The Socket API
ZeroMQ提供了一个熟悉的基于套接字的API,这需要我们付出很大的努力来隐藏一堆消息处理引擎。然而,其结果将慢慢修正您关于如何设计和编写分布式软件的认识。
套接字实际上是网络编程的标准API。ZeroMQ特别适合开发人员的一点是,它使用套接字和消息,而不是其他任意的概念集。
几个基本应用:
创建、销毁sockets
设置和获取sockets配置
zmq_setsockopt(), zmq_getsockopt()
创建连接
收发消息
zmq_msg_send(), zmq_msg_recv()
在ZeroMQ,“sockets是属于我们的",但是,消息是你可以拥有的。
Plugging Sockets into the Topology
通常,使用zmq_bind()的节点是服务端,,使用zmq_connect()的节点是客户端。
ZeroMQ连接与传统TCP连接有些不同的地方,如下:
ZeroMQ可以使用任意的连接方式,zmq_inproc(), zmq_ipc(), zmq_tcp(), zmq_pgm(), and zmq_epgm().
一个socket可以有多个传出和传入连接。
ZeroMQ没有accept()方法,当一个socket绑定到endpoint后,会自动开始接收连接。
ZeroMQ在后台连接,且会断线重连。
你的应用程序不能直接使用这些connections,它们被封装在socket。
只要客户端节点执行zmq_connect(),连接就存在,并且该节点可以开始向套接字写入消息。在某个阶段(希望在消息队列排得太长以至于开始被丢弃或客户端阻塞之前),服务器启动,执行zmq_bind(), ZeroMQ开始传递消息。
一个服务节点可以绑定多个endpoints,而只需要用一个socket。用法如下:
zmq_bind (socket, "tcp://*:5555"); zmq_bind (socket, "tcp://*:9999"); zmq_bind (socket, "inproc://somename");
对于大多数传输,不能绑定到相同的端点两次,例如在UDP中。然而,ipc传输允许一个进程绑定到已经被第一个进程使用的端点。它的意思是允许进程在崩溃后恢复。
套接字有许多类型,套接字类型定义了套接字的语义,以及套接字向内和向外路由消息的策略、队列等。您可以将某些类型的套接字连接在一起,例如,发布者套接字和订阅者套接字。
Sending and Receiving Messages
zmq_msg_send() and zmq_msg_recv()
ZeroMQ的I/O模型与传统的TCP模型有着非常大的区别:
ZeroMQ套接字携带消息,类似UDP,而不是TCP那样的字节流。ZeroMQ消息是指定长度的二进制数据。它们的设计是为了性能而优化的,所以有点棘手。
ZeroMQ套接字在后台线程中执行I/O。这意味着消息到达本地输入队列,并从本地输出队列发送,无论应用程序正在忙什么。
根据套接字类型,ZeroMQ套接字具有内置的一对到n的路由行为。
zmq_send()方法实际上不会将消息发送到套接字连接。它将消息排队,以便I/O线程可以异步发送它。它不会阻塞,除非在某些异常情况下。因此,当zmq_send()返回到应用程序时,不一定发送消息。
Unicast Transports 单一传输
ZeroMQ提供一个单一传输(inproc, ipc, and tcp)和多播传输(epgm, pgm)的集。
大多数情况下,tcp,是一个断开连接的tcp传输。它具有弹性、便携性和足够快的速度,适用于大多数情况。我们称其为断开的连接,因为ZeroMQ的tcp传输不要求终端在连接到它之前存在。客户机和服务器可以在任何时候连接和绑定,可以往返,并且对应用程序保持透明。
ipc不支持Windows。
线程间传输(inproc)是一种连接的信令传输。它比tcp或ipc快得多。与tcp和ipc相比,此传输有一个特定的限制:服务器必须在任何客户端发出连接之前发出绑定。这个问题在ZeroMQ v4.0和更高版本中得到了修复。
ZeroMQ is Not a Neutral Carrier
ZeroMQ不是中立的载体:它在它使用的传输协议上强加了一个帧。这种帧与现有协议不兼容,后者倾向于使用自己的帧。例如,比较HTTP请求和ZeroMQ请求,两者都是通过TCP/IP。
从3.3版开始,ZeroMQ就有了一个套接字选项ZMQ_ROUTER_RAW,可以在不使用ZeroMQ帧的情况下读写数据。您可以使用它来读取和写入适当的HTTP请求和响应。
I/O Threads
我们说过ZeroMQ在后台线程中执行I/O。除了最极端的应用程序外,一个I/O线程(用于所有套接字)对所有应用程序来说都足够了。当您创建一个新上下文时,它从一个I/O线程开始。一般的经验法则是允许每秒每g字节的数据输入或输出一个I/O线程。要增加I/O线程的数量,在创建任何套接字之前使用zmq_ctx_set()调用。
我们已经看到,一个套接字可以同时处理数十个,甚至数千个连接。这对如何编写应用程序有根本性的影响。传统的网络应用程序每个远程连接有一个进程或线程,该进程或线程处理一个套接字。ZeroMQ允许您将整个结构分解为单个进程,然后根据需要进行分解。