ZeroMQ:云时代极速消息通信库(大规模|可扩展|低成本|高效率解决之道,大规模分布式|多线程应用程序|消息传递架构构建利器)
【美】Pieter Hintjens(皮特.亨特金斯)著
卢涛 李颖 译
ISBN 978-7-121-25311-9
2015年3月出版
定价:108.00元
536页
16开
编辑推荐
请潜心研究MQ(又名ZeroMQ)这个智能套接字库,它让你的应用程序能够获得快速、简便、基于消息的并发性。有了这本快节奏的指南,你将在实践中学习如何使用这个可扩展、轻量级且高度灵活的网络工具,从而在集群、云服务端等各种多系统环境之间交换消息。
MQ的维护者Pieter Hintjens带你观察现实世界的应用程序,并用C语言编写的扩展例子帮助你使用MQ的API、套接字和模式。了解如何使用特定的MQ编程技术,构建多线程应用程序,并创建自己的消息传递架构。你会学到MQ如何与多种编程语言和大多数操作系统共用,只有很少的成本或根本没有成本。
□了解MQ的主要模式:请求-应答、发布-订阅和管道
□通过建立几个小应用程序来使用MQ套接字和模式
□通过工作实例探索MQ的请求-应答模式的高级使用
□构建一个在代码或硬件出现故障时保持工作可靠性的请求-应答模式
□扩展MQ的核心发布-订阅模式的性能、可靠性、状态分发与监控
□了解用MQ来构建分布式架构的技术
□探索为分布式应用程序建立一个通用的框架有什么要求
内容提要
《ZeroMQ:云时代极速消息通信库》介绍ZeroMQ 的API、套接字和模式的使用。通过建立应用程序来讲解如何使用ZeroMQ 编程技术构建多线程应用程序,并创建自己的消息传递架构。《ZeroMQ:云时代极速消息通信库》设计了大量工作实例来实现请求- 应答模式的高级使用和容错性,并对发布- 订阅模式的性能、可靠性、状态分发与监控进行了扩展。
《ZeroMQ:云时代极速消息通信库》面向的读者是希望制作大规模分布式软件的专业程序员和有志于这方面研究的专业人士,旨在帮助他们解决大规模、可扩展、低成本、高效率的问题,书中还展现了ZeroMQ所需的网络和分布式计算概念。
目录
前言 ..................................xix
第1 部分学习如何使用MQ 来开展工作
第1 章基础知识 ................. 3
修复这个世界 ..................3
本书的读者对象 ...............5
获取示例 ..........................5
问过就必有收获 ...............5
在字符串上的小注解 .....10
版本报告 ........................12
获得消息 ........................12
分而治之 ........................16
用MQ 编程 .................21
获取正确的上下文 ..22
执行彻底的退出 ......22
为什么我们需要MQ ..23
套接字的可扩展性 .........27
从MQ v2.2 升级到MQ v3.2 ...............................28
警告:不稳定的典范! ..29
第2 章套接字和模式 ........ 31
套接字API .....................32
把套接字接入网络拓扑 .....................................32
使用套接字来传输数据 ......................................34
单播传输 .................35
MQ 不是一个中性载体 ....................................35
I/O 线程 ...................36
消息传递模式 ................37
高级别消息传递模式 ..........................................38
处理消息 .................38
处理多个套接字 ......41
多部分消息 .............44
中间层及代理 ..........45
动态发现问题 ..........46
共享队列(DEALER 和ROUTER 套接字) .......48
MQ 的内置代理功能 .......................................53
传输桥接 .................55
处理错误和ETERM.......56
处理中断信号 ................61
检测内存泄漏 ................63
使用MQ 编写多线程程序 ......................................64
线程间信令(PAIR 套接字) .....................................69
节点协调 ........................71
零拷贝 ............................75
发布- 订阅消息封包 ......76
高水位标记 ....................78
消息丢失问题的解决方案 .........................................80
第3 章高级请求- 应答模式 ......................................... 83
请求- 应答机制 .............83
简单的应答封包 ......84
扩展的应答封包 ......84
这有什么好处呢 ......87
请求- 应答套接字回顾 ......................................88
请求- 应答组合 .............88
REQ 到REP 组合 ....89
DEALER 到REP 组合 .......................................89
REQ 到ROUTER 组合 .......................................90
DEALER 到ROUTER 组合 ...............................90
DEALER 到DEALER 组合 ...............................90
ROUTER 到ROUTER 组合 ...............................90
无效组合 .................91
探索ROUTER 套接字 ...91
身份和地址 .............92
ROUTER 错误处理 .93
负载均衡模式 ................94
ROUTER 代理和REQ 工人 ...............................95
ROUTER 代理及DEALER 工人 ........................97
负载均衡的消息代理 ..........................................98
用于MQ 的一个高级别的API ............................. 105
高级别API 的特点 107
CZMQ 高级别API 108
异步客户端/ 服务器模式 ........................................ 115
能够工作的示例:跨代理路由 ............................... 120
建立详情 ............... 120
单集群架构 ........... 121
扩展到多个集群 .... 122
联盟与对等比较 .... 124
命名规范 ............... 126
状态流原型 ........... 127
本地流和云端流原型 ........................................ 130
总结 ....................... 137
第4 章可靠的请求- 应答模式 .................................... 147
什么是“可靠性” ......... 147
可靠性设计 .................. 148
客户端可靠性(懒惰海盗模式) ............................. 149
基本可靠队列(简单海盗模式) ............................. 154
健壮的可靠队列(偏执海盗模式) .......................... 157
信号检测 ...................... 166
置若罔闻地将它关闭 ........................................ 166
单向信号检测 ........ 167
乒乓信号检测 ........ 167
针对偏执海盗的信号检测 ................................ 168
合同和协议 .................. 170
面向服务的可靠队列(管家模式) .......................... 170
异步管家模式 .............. 195
服务发现 ...................... 201
幂等服务 ...................... 203
断开连接的可靠性(泰坦尼克模式) ...................... 203
高可用性对(双星模式) ......................................... 216
详细需求 ............... 218
避免脑裂症状 ........ 220
双星实现 ............... 221
双星反应器 ........... 228
无代理可靠性(自由职业者模式) .......................... 234
模型一:简单的重试和故障转移 ..................... 235
模型二:粗暴***屠杀 .................................... 238
模式三:复杂和讨厌的 .................................... 244
结论 ............................. 256
第5 章高级发布- 订阅模式 ....................................... 257
发布- 订阅模式的优点和缺点 ................................ 257
发布- 订阅跟踪(特浓咖啡模式) .......................... 259
最后一个值缓存 ........... 262
慢速订阅者检测(自杀蜗牛模式) .......................... 267
高速订阅者(黑盒模式) ......................................... 270
可靠的发布- 订阅(克隆模式) .............................. 272
集中式与分散式 .... 273
将状态表示为键- 值对 .................................... 273
得到带外的快照 .... 284
重新发布来自客户端的更新 ............................ 290
处理子树 ............... 295
临时值 ................... 298
使用反应器 ........... 306
在双星模式中添加可靠性 ................................ 311
集群的散列映射协议 ........................................ 321
构建一个多线程栈和API ................................. 325
第2 部分使用MQ 的软件工程
第6 章 MQ 社区 .......... 341
MQ 社区的架构......... 342
如何制作真正的大型架构 ....................................... 343
软件架构的心理学 344
合同 ....................... 346
过程 ....................... 348
疯狂,美丽,并且容易 .................................... 348
陌生人,遇见陌生人 ........................................ 349
无限的财富 ........... 349
照管和培育 ........... 350
MQ 过程:C4 ............ 351
语言 ....................... 351
目标 ....................... 352
热身 ....................... 354
许可和所有权 ........ 355
对补丁程序的要求 356
开发过程 ............... 357
建立稳定的版本 .... 361
公共合同的演变 .... 362
一个实际例子 .............. 364
Git 分支是有害的 ......... 368
简单性与复杂性的对比 .................................... 369
更改延迟 ............... 369
学习曲线 ............... 369
出故障的成本 ........ 369
前期协调 ............... 369
可扩展性 ............... 370
惊奇和期望 ........... 370
参与的经济学 ........ 370
在冲突中的强壮性 370
隔离的保证 ........... 370
能见度 ................... 371
结论 ....................... 371
为创新而设计 .............. 371
双桥传说 ............... 371
MQ 的路线图是如何失去的 .......................... 372
垃圾桶化的设计 .... 374
复杂化的设计 ........ 376
简约化的设计 ........ 377
职业倦怠 ...................... 379
成功模式 ...................... 380
懒惰的完美主义者 381
仁慈暴君 ............... 381
天和地 ................... 381
门户开放 ............... 381
大笑的小丑 ........... 382
留心的将军 ........... 382
社会工程师 ........... 382
不朽的园丁 ........... 382
滚石 ....................... 382
海盗帮 ................... 383
快闪族 ................... 383
加那利看守 ........... 383
执行绞刑的刽子手 383
历史学家 ............... 383
煽动者 ................... 384
神秘人 ................... 384
第7 章使用MQ 的高级架构 .................................... 385
用于弹性设计的面向消息模式 ............................... 386
第1 步:内部化的语义 .................................... 387
第2 步:描绘一个粗略的架构 ......................... 387
第3 步:决定合同 388
第4 步:编写一个最小的端到端解决方案 ...... 388
第5 步:解决一个问题,然后重复 ................. 389
Unprotocol ................... 389
合同是艰难的 ........ 390
如何编写Unprotocol ........................................ 391
为什么使用GPLv3 的公开规范 ....................... 392
使用ABNF ............ 393
廉价或讨厌的模式 393
序列化数据 .................. 395
MQ 组帧 ............. 396
序列化语言 ........... 396
序列化库 ............... 397
手写的二进制序列化 ........................................ 399
代码生成 ............... 400
传输文件 ...................... 406
状态机 .......................... 417
使用SASL 认证 ........... 424
大型文件发布:FileMQ .......................................... 426
为什么要制作FileMQ ...................................... 426
最初的设计切片:API ..................................... 426
最初的设计切片:协议 .................................... 427
构建和尝试FileMQ.......................................... 429
内部架构 ............... 430
公共API ................ 431
设计说明 ............... 432
配置 ....................... 433
文件稳定性 ........... 434
递交通知 ............... 434
符号链接 ............... 435
恢复和后期加入者 435
测试用例:曲目工具 ........................................ 437
得到一个官方端口号 ... 439
第8 章分布式计算的框架 .......................................... 441
用于现实世界的设计 ... 442
无线网络的秘密生活 ... 443
为什么网状网络现在还没出现 ......................... 444
一些物理知识 ........ 445
现状是什么 ........... 446
结论 ....................... 448
发现 ............................. 448
通过原始套接字先发制人的发现 ..................... 448
使用UDP 广播协同发现 .................................. 450
一台设备上的多个节点 .................................... 455
设计API ................ 456
关于UDP 的更多内容 ...................................... 465
分拆一个库项目 ........... 466
点对点消息传递 ........... 467
UDP 信标帧 .......... 467
真正的对等连接(和谐模式) .......................... 469
检测失踪 ............... 471
群发消息 ...................... 472
测试与模拟 .................. 474
使用断言 ............... 474
前期测试 ............... 475
Zyre 测试仪 ........... 476
测试结果 ............... 479
跟踪活动 ............... 481
处理阻塞节点 ........ 481
分布式日志记录和监视 484
一个合理的最小实现 ........................................ 485
协议断言 ............... 488
二进制日志记录协议 ........................................ 489
内容分发 ...................... 490
编写Unprotocol ........... 493
结论 ............................. 494
第9 章后记 ................... 497
番外篇 .......................... 497
Rob Gagnon 的故事 .......................................... 497
Tom van Leeuwen 的故事 ................................. 497
Michael Jakl 的故事 ......................................... 498
Vadim Shalts 的故事 ......................................... 498
本书是如何诞生的 ....... 499
消除摩擦 ...................... 500
许可 ............................. 502
索引 ................................ 503
精彩节摘
序
ZeroMQ 是iMatix 开发的以消息为导向的开源中间件库,它类似于标准Berkeley 套接字,支持多种通信模式(扇出、发布- 订阅、任务分配和请求- 应答)和传输协议(进程内、进程间、TCP 和多播),可以用作一个并发框架。其核心由C 编写,支持C++、Java 等多种语言的API,能在大部分现代平台上运行。它的运行速度很快,其异步模型具有高可扩展性。ZeroMQ 中的Zero(零)代表简约并涵盖不同目标:零代理、零延迟、零管理、零成本等。
本书源自ZeroMQ 的参考手册,通过社区共同开发而成,数百人为本书做出了贡献,包括用各种编程语言编写的示例。本书也为运作一个成功的社区提供了范例。
值得一提的是,本书作者Pieter Hintjens 是iMatix 公司的首席执行官,他于2010 年被查出患了晚期癌症,动了多次手术并化疗6 个月,但2011 年仍然坚持继续完成这本书的写作。这种奋不顾身的专业精神值得我们学习。
感谢电子工业出版社计算机出版分社的张春雨编辑选择我们翻译本书,感谢刘舫编辑,她从专业的角度对译文进行了把关,并进行了许多润色,使之更具可读性。
感谢李绿霞、卢林、陈克非、李洪秋、张慧珍、李又及、卢晓瑶、陈克翠、汤有四、李阳、刘雯、贾书民、苏旭晖对本书翻译工作做出的贡献。
还要感谢我们的儿子卢〇一小朋友,他知道我们在翻译书稿就常常自己安静地读书和玩耍,还放弃了很多出去玩的机会,让我们能够专注于本书的翻译,本书的出版也有他的一份贡献。
最后希望这本书对读者有帮助。但由于译者经验和水平有限,译文中难免有不妥之处,恳请读者批评指正!
卢涛李颖
2014 年12 月8 日
作者简介
Pieter Hintjens,iMatix公司的CEO和首席软件设计师,该公司创建了MQ。他是自由信息基础设施基金会(FFII)的前任会长,欧洲专利大会和数字标准组织的创办人,Wikidot公司的前CEO,他还是MQ的一位维护者。
媒体评论
本年度你能读到的最好的爱与套接字的故事。
——Alexis Richardson VMware的高级主管和新人训练师。
前言
MQ 的一百字概括
MQ(也称为ZeroMQ、0MQ 或zmq)看起来像一个可嵌入的网络库,但其作用就像一个并发框架。它为你提供了在各种传输工具,如进程内、进程间、TCP 和组播中进行原子消息传送的套接字。你可以使用各种模式实现N 对N 的套接字连接,这些模式包括扇出、发布- 订阅、任务分配和请求- 应答。它的速度足够快,因此可充当集群产品的结构。
它的异步I/O 模型提供了可扩展的多核应用程序,用异步消息来处理任务。它有多种编程语言的API,并可运行在大多数操作系统上。MQ 是iMatix(http://www.imatix.com)开发的,并在LGPLv3 许可下开源。
零之禅
MQ 中的 关乎权衡。一方面,MQ 这个奇怪的名字使其在谷歌和Twitter 上降低了知名度。另一方面,它惹恼了一些丹麦人(译者注: 是丹麦语字母表中的字母),他们写给我们如下的东西,比如“MG rtfl”(译者注:把 替换成O 后表示“天哪,笑翻了”)、“ 不是一个有趣的零!”(译者注:早期计算机输出中用这个符号表示数字0,以便与字母O 区分)和“Rdgrd med Flde!”(这显然是一种侮辱,意思是“愿你的邻居是格伦德尔的直系后裔!”)(译者注:在古英国史诗《贝奥武夫》中,格伦德尔是一只雄性怪兽,这里作者好像是在误导,rdgrd med flde,意为“浇了奶油的红莓布丁”,是个非常经典的丹麦语绕口令,它难倒了很多外国人,因为这短短的一句话中包括了三个“”(两种不同的发音方式)、咽喉擦音r、重音gr 组合和软化的d(发音类似于英语with 中的th)。)这毁誉参半的两方面似乎是一个公平的交易。
最初,MQ 中的“零”是为了表示“零代理”和(尽可能接近)“零延迟”。但从那时起,它已经涵盖了不同的目标:零管理、零成本、零浪费。更一般的,“零”是指贯穿项目的简约文化。我们通过消除复杂性,而不是通过公开新功能来增加威力。
本书的历程
在2010 年的夏天,MQ 仍是一个名不见经传的小众库,它由相当简洁的参考手册和一个活跃但精炼的wiki 来描述。那时,Martin Sustrik 和我坐在布拉迪斯拉发Kyjev 酒店的酒吧里,密谋如何让MQ 获得更广泛的普及。Martin 写了大部分的MQ 代码,而我提供了资金并组织了社区。因为某种原因,我们一致认为MQ 需要一个更简单的新网站,并需要为新用户写一本基本指南。
Martin 收集了一些要讲解的主题。由于在此之前,我连一行MQ 代码都没写过,因此这本书的写作过程成了一个活学活用的见证。当我通过简单的例子进入复杂的工作时,我试着回答了很多在邮件列表上见过的问题。因为30 年来我一直在构建大型架构,所以我有很多问题渴望用MQ 来解决。令人惊讶的是,用MQ 来解决问题所获得的结果大多是简单而优雅的,甚至当我用C 语言工作时,学习MQ 和用它解决实际问题也会使我感到一种纯粹的快乐,这使我在几年的停顿后,再一次回归编程领域。而往往,我们起初也不知道它“应该”如何完成某项工作,在使用过程中,我们不断地对MQ 进行着改进。
因为从一开始,我就想把这本指南做成一个社区项目,所以我把它放到GitHub 上,让别人通过提出请求的方式为本书做出贡献。这种做法被某些人认为是激进的,甚至是低俗的。我们实现了分工:我负责写作和制作原始的C 语言示例,其他人帮助修复文本中的错误并把示例翻译成其他语言。
这种模式工作得比我想象的更好。现在你可以找到所有示例的多种语言版本,许多例子甚至有十几种语言版本。它是一块编程语言的罗塞塔石碑(译者注:刻有古埃及国王托勒密五世登基的诏书的石碑。上面用希腊文字、古埃及文字和当时的通俗体文字刻了同样的内容),这本身就是一个有价值的结果。我们建立了高分标准:翻译程度达到80%,每种语言都有自己的指南。PHP、Python、Lua 和Haxe 都达到了这个目标。人们要求我们创建PDF 文件,我们就创建好后提供给他们。人们要求提供电子书,他们也如愿以偿了。目前,这本指南得到了大约一百多人的帮助。
该指南实现了普及MQ 的目标。这种风格取悦了大多数人但也惹恼了一些人,这是自然的。2010 年12 月,我在MQ 和指南上的工作停顿了下来,因为我查出自己患了晚期癌症,动了多次手术并化疗6 个月。当我在2011 年年中再度拾起这项工作时,它开始在可以想象的最大的用例之一上爆发,即:在全球最大的电子公司的手机和平板电脑上使用MQ。
但是,本指南的目标从一开始就是一本印刷书籍。所以,在2012 年1 月我收到Bill Lubanovic 发来的一封电子邮件,这是令人兴奋的,他把我介绍给O’Reilly 公司的Andy Oram 编辑,建议出一本MQ 的图书。“当然!”我说,“可我在哪里签名呢?我需要付多少钱?呵呵,我能得到钱吗?所有我需要做的就是完成它吗?”
当然,只要O’Reilly 发布一本MQ 图书,其他出版社就会开始给潜在的作者发送电子邮件约稿。明年你可能会看到大量的MQ 图书现身。这是很好的。我们的小众库已经成为主流,并值得拥有六英寸的书架空间。我要向其他MQ 图书的作者致歉,我们已经设置了可怕的高门槛,我的建议是让你的书具有互补性,也许可以专注于一种特定的语言、平台或模式。
这就是社区的神奇和力量:如果你创建的社区能成为在某一个领域中的第一个社区,并保持健康发展,你就将永远占据这个领域的领导地位。
读者对象
本书是为专业程序员编写的,旨在帮助他们了解如何制作将主宰未来计算的大规模分布式软件。我们假设你能够阅读C 代码,因为这里的大多数示例都用C 语言编写(尽管MQ被用在许多语言中)。我们假设你关注规模,因为MQ解决了上述所有其他的问题。
我们假设你需要用最少的成本获得最好的结果,因为否则你不会欣赏MQ 所做的权衡。除了这些基本的背景,我们还试图为你呈现使用MQ 将需要的所有网络和分布式计算的概念。
本书所使用的约定
本书使用以下印刷约定:
斜体(Italic)
用于表示新的术语、命令或命令行选项、URL、电子邮件地址、文件名和文件扩展名。
等宽字体(Constant width)
用于程序清单,以及段落中引用的程序元素,如变量、函数名、数据类型和环境变量。
等宽粗体(Constant width bold)
用于表示由用户输入的命令行。
等宽斜体(Constant width italic)
用于表示应被替换为用户提供的有意义的值的预留位置。
此图标表示提示、建议或一般的注意。
中文版书中切口以“”表示原书页码,便于读者与原英文版图书对照阅读,本书的索引中所列的页码为原英文版页码。
使用代码示例
代码示例都在在线存储库中,它位于https://github.com/imatix/zguide/tree/master/examples/。你会发现每一个例子都被翻译成其他数种语言。这些例子都在MIT/X11 下授权,详情请查看该目录中的LICENSE 许可文件。本书正文解释了在各种情况下如何运行每个示例。
我们欢迎在使用代码示例时署名,但不强制要求这么做。一个署名通常包括标题、作者、出版商和ISBN。例如:“ZeroMQ by Pieter Hintjens (O’Reilly). Copyright 2013 Pieter Hintjens, 978-1-449-33406-2.”。
如果你发现自己对书中代码的使用有失公允,或是违反了前述条款,敬请通过permissions@oreilly.com 与我们联系。
Safari? Books Online
Safari Books Online 是一家按需所取的数字图书馆,它同时提供来自世界各地领先的技术和业务作者的书籍和视频两种形式的专业内容。
专业技术人员、软件开发人员、网页设计师,以及商业和创意专业人士使用Safari 联机丛书作为研究,是解决问题、学习和认证培训的主要资源。
Safari Books Online 提供了一系列的产品组合和针对组织、政府机构和个人的定价方案。用户有机会在一个完全可搜索的数据库中访问成千上万的书籍、培训视频和即将出版的原稿,它们来自O’Reilly Media、Prentice Hall Professional、Addison-Wesley Professional、Microsoft Press、Sams、Que、Peachpit Press、Focal Press、Cisco Press、John Wiley & Sons、Syngress、Morgan Kaufmann、IBM Redbooks、Packt、Adobe Press、FT Press、Apress、Manning、New Riders、McGraw-Hill、Jones & Bartlett、Course Technology 以及大量其他出版商。有关Safari Books Online 的更多详细信息,请访问我们的网站。
如何联系我们
请将对本书的评价和存在的问题通过如下地址告知出版者:
美国:
O’Reilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
中国:
北京市西城区西直门南大街2 号成铭大厦C 座807 室(100035)
奥莱利技术咨询(北京)有限公司
O’Reilly 的每一本书都有专属网站,你可以在那里找到关于本书的相关信息,包括勘误列表、示例代码以及其他信息。本书的网站地址是:http:/bit.ly/ZeroMQ-OReilly
对于本书的评论和技术性的问题,请发送电子邮件到:bookquestions@oreilly.com
关于我们的书籍、课程、会议和新闻的更多信息,请参阅我们的网站http://www.oreilly.com。
在Facebook 上找到我们:http://facebook.com/oreilly
在Twitter 上关注我们:http://twitter.com/oreillymedia
在YouTube 上观看我们:http://www.youtube.com/oreillymedia
致谢
感谢Andy Oram 使本书能够在O’Reilly 出版并对此书进行了编辑。
感谢Bill Desmarais、Brian Dorsey、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、Mihail Minkov、Jeremy Avnet、Michael Compton、Kamil Kisiel、Mark Kharitonov、Guillaume Aubert、Ian Barber、Mike Sheridan、Faruk Akgul、Oleg Sidorov、Lev Givon、Allister MacLeod、Alexander D’Archangel、Andreas Hoelzlwimmer、Han Holl、Robert G. Jakabosky、Felipe Cruz、Marcus McCurdy、Mikhail Kulemin、Dr. Gerg rdi、Pavel Zhukov、Alexander Else、Giovanni Ruggiero、Rick “Technoweenie”、Daniel Lundin、Dave Hoover、Simon Jefford、Benjamin Peterson、Justin Case、Devon Weller、Richard Smith、Alexander Morland、Wadim Grasza、Michael Jakl、Uwe Dauernheim、Sebastian Nowicki、Simone Deponti、Aaron Raddon、Dan Colish、Markus Schirp、Benoit Larroque、Jonathan Palardy、Isaiah Peng、Arkadiusz Orzechowski、Umut Aydin、Matthew Horsfall、Jeremy W. Sherman、Eric Pugh、Tyler Sellon、John E. Vincent、Pavel Mitin、Min RK、Igor Wiedler、Olof kesson、Patrick Lucas、Heow Goodman、Senthil Palanisami、John Gallagher、Tomas Roos、Stephen McQuay、Erik Allik、Arnaud Cogoluègnes、Rob Gagnon、Dan Williams、Edward Smith、James Tucker、Kristian Kristensen、Vadim Shalts、Martin Trojer、Tom van Leeuwen、Hiten Pandya、Harm Aarts、Marc Harter、Iskren Ivov Chernev、Jay Han、Sonia Hamilton、Nathan Stocks、Naveen Palli 和 Zed Shaw 对这项工作做出的贡献。
感谢Martin Sustrik 多年来在ZeroMQ 上所做的令人难以置信的工作。
感谢Stathis Sideris 为Ditaa(http://www.ditaa.org)做出的贡献。
本文出自 “博文视点官方博客” 博客,请务必保留此出处http://bvbroadview.blog.51cto.com/3227029/1625734
原文:http://bvbroadview.blog.51cto.com/3227029/1625734