0. PUB/SUB, XPUB/XSUB

  • filtering happens at publisher sides when sockets are using a connected protocol(tcp or ipc or inproc)
  • there are meta-info exchange between SUB and PUB, but on API level,only allow message to flow from PUB to SUB.
  • SUB socket can not send message on API level, but actually when user adds filter, there are meta information sent from subscriber to publisher, and XPUB can receive that(PUB cannot).
  • when XPUB receives meta info, this info must be forwarded to the original PUB server, this is done by XSUB, as following model illustrated: PUB->XSUB<-->XPUB->SUB. since SUB can not send, so it is not capable of serving as proxy.

1. REQ/REP works in a strict request-reply mode

  • when server receives a request, it has to reply it until it could issue another read.

  • one client socket can connected to several servers at the same time, send() is distributed evenly among all connections:
    • c1 connect() to s1.
    • c1 connect() to s2.
    • c1 send() will write to s1.
    • c1 recv() from s1.
    • c1 send() again, this time message is sent to s2.
  • if there are multiple clients connected to the same REP server, and multiple clients send request to server at the same time, then server will have to handle each of these request one by one.
    • A connects to C.
    • B connects to C.
    • A sends request r1 to C.
    • B sends request r2 to C.
    • C accepts r1.
    • C processes r1, and at the same time, C can not read any other requestes before replying to r1.
    • C replys to r1.
    • C accepts r2 and does some processing and replys to it.
    • by doing so a single REP socket can handle multiple connected REQ sockets(posix socket api cannot do that, it requires one socket per connection at server side.)

2. identity/envelop of message

  • why do we need ROUTER/DEALER sockets?

    • use it to work as proxy.
    • REQ/REP works in a strict request/reply mode, and this is not scalable when many clients are connected to a single server(it has to round-robin simultaneous requests: recv message, forward message, wait for replying message, forward reply message and then handle next recv). In contrast, ROUTER is not restricted to this model, and it can perform several recv() in a row before reply to any of them.
      • r1 sends to server s0.
      • r2 sends to server s0.
      • s0 forwards r1 to some REP server s1.
      • s0 forwards r2 to some REP server s2.(REP socket doesn't allow this, since r1 is not replied yet)
      • s0 receives reply from s1 and forward it to r1.
      • s0 receives reply from s2 and forward it to r2.
  • every ROUTER socket need to preppend an unique id to the message before handing that message to the application.
    • this id can be set by incoming socket by calling zmq.setsockopt(zmq.IDENTITY, $id) in client side.
    • or if not set by incoming socket, ROUTER socket has to choose one for it.
    • if there are id clash, the incoming connection will be turned down(connection refused).
  • for every REQ socket or REP socket when receiving a message, it will strip ALL the prepended id(and holds it internally), and then hands the message to caller.
    • socket will keep the id(s) it stripped from the massage for further use.
    • when socket need to send message back, it will preppend thoese id(s) it holds to the message before sending it out.
  • DEALER sends message to all connected clients in a round-robin way and messages received are fair-queued.[5]
    • no extra info will be added to the message to send.
    • no extra info will be stripped from the received message.
    • DEALER is completely agnostic to all connected clients.
  • a simple example: c1 ---> proxy1(ROUTER/DEALER) ---> proxy2(ROUTER/DEALER) ---> s1
    • c1 sends message: delimiter|msg
    • proxy1 ROUTER socket recv message: delimiter|msg, and preppend an id to the message: id1|delimiter|msg.
    • proxy1 sends id1|delimiter|msg to proxy2 throught DEALER socket.
    • proxy2 ROUTER socket recv message: id1|delimiter|msg, and preppend an id to the massage, id2|id1|delimiter|msg.
    • proxy2 sends id2|id1|delimiter|msg to s1 throught its DEALER socket.
    • s1 recv message: id2|id1|delimiter|msg, it will strip all ids and hands "msg" to caller.

    ==> then s1 trys to reply message:

    • before message is sent out, it will preppend the ids it get to the message.
    • every ROUTER will strip the first id off the package and use it to identified which connection to send the message when it try to send the message.
    • that is, proxy2 receives id2|id1|delimiter|rep_msg, and sends out id1|delimiter|rep_msg.
    • proxy1 receives id1|delimiter|rep_msg and works the same way and sends out delimiter|rep_msg.
    • c1 recv delimiter|rep_msg, and strip the delimiter before handing it to caller.
  • router to router is possible, but it is tricky to work, eg, router1 connects to router2:
    • r1 connected to r2 successfully.
    • at this point, r1 doesn't know the id of r2, so r1 could not send message to r2(recall that, every router need to strip an id from the message to identify the connection to send the message)
    • r2 can send message to r1, if and only if r2 could SOMEHOW get to know the id of r1 before hand.
    • the only way to accomplish step 3 is let r1 hardcodes its identity, then r2 could use this hardcoded id to send message back to r1.
    • r1 acts as server, it will bind to local port, thus r1 sets its identity won't help.
    • the only way for r1 to get the id of r2 is receiving message from r2,(ROUTER announces the identity of a connection only when receiving message from peer.[6])

3. reliability at client side read

  • server side uses poll to sit on the socket(or it could issue blocking read, timeout read), no exception will throw normally.
  • client should perform a timeout read, and when timeout occurs, retry several times, client should abort the connection if read still fails in the end. instead, start a new connection to server.
  • connection is cheap in this regard, and users are encouraged to kill bad connection and start a new one.[4][7]

Reference:

  1. http://api.zeromq.org/
  2. http://zguide.zeromq.org/
  3. http://pyzmq.readthedocs.io/en/latest/api/
  4. https://news.ycombinator.com/item?id=4161073
  5. http://lucumr.pocoo.org/2012/6/26/disconnects-are-good-for-you/
  6. http://zguide.zeromq.org/page:all#Recap-of-Request-Reply-Sockets
  7. http://zguide.zeromq.org/page:all#Identities-and-Addresses
  8. http://zguide.zeromq.org/page:all#Client-side-Reliability-Lazy-Pirate-Pattern

zmq 学习笔记的更多相关文章

  1. zmq学习笔记

    1 zmq_socket(3) Manual Page 1.1 一个socket可连接多个对端socket: 通过使用多个zmq_connect() 1.2 一个socket可绑定到多个地址上接受连接 ...

  2. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  3. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  4. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  5. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  6. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  7. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

  8. CSS学习笔记

    CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...

  9. HTML学习笔记

    HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...

随机推荐

  1. atitit.软件开发方法总结O6

    atitit.软件开发方法总结O6 #--cmm/cmmi  都晓得这个. #--IPD集成产品开发 结构化的流程 IPD工具:包括业务及技术上的共工具. 5.考评:包括团队和个人绩效考核两个方面:首 ...

  2. java生成生成图片缩略图

    /** * */ package com.fkhwl.fkhserver.core.utils; import java.awt.Image; import java.awt.image.Buffer ...

  3. Leetcode 83 Remove Duplicates from Sorted List 链表

    就是将链表中的重复元素去除 我的方法很简单就是如果链表的前后元素相同的话,将后一个元素删除 /** * Definition for singly-linked list. * struct List ...

  4. 关于OBJ/LIB格式,我以前有个总结

    1.VC,GCC obj,lib格式为coff 可相互通用2.vc,gcc的obj,lib可通过coff2omfn转成OMF格式,但VC在编译时要加/Zl选项3.VC,GCC的typelib可通过co ...

  5. linux进阶

    常用命令 rpm -q centos-release 查看centos版本 whereis java 查看文件安装路径 which java 查看可执行文件路径 echo $PATH echo $JA ...

  6. 【地图API】地址录入时如何获得准确的经纬度?淘宝收货地址详解

    用户需求:管理者需要录入一批商户,并在地图上把商户展示出来.但发现一些商户的地址描述并不清楚,导致商户位置出错.如何获得更加准确的商户位置呢? 分析:假设地址准确的,可以通过地址解析,得到准确的经纬度 ...

  7. 诚聘:全栈开发人员,三线城市10-16K

    北京快鸽联盟信息技术有限公司成立于2013年,专注于校园及社区快递和增值服务.目前已有十余家各地分部,并与上百所大学,各大快递和电商公司有密切合作,年处理快件量超千万,长期处于行业领先地位. 诚聘全栈 ...

  8. asp.net 读取RedisSessionStateProvider配置

    最近项目遇到需要读取RedisSessionStateProvider配置文件applicationName节点,如: 读取的方法有很多: 1直接读取web.config文件, void test1( ...

  9. Spring MVC3返回JSON数据中文乱码问题解决(转)

    Spring MVC3返回JSON数据中文乱码问题解决 查了下网上的一些资料,感觉比较复杂,这里,我这几使用两种很简单的办法解决了中文乱码问题. Spring版本:3.2.2.RELEASE Jack ...

  10. PCM音频设备的操作(转)

    对音频设备的操作主要是初始化音频设备以及往音频设备发送 PCM(Pulse Code Modulation)数据.为了方便,本文使用 ALSA(Advanced Linux Sound Archite ...