首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 互联网 >

zeroMQ初体验-9.幽雅的扩展(代理模式)

2012-07-03 
zeroMQ初体验-9.优雅的扩展(代理模式)前面所谈到的网络拓扑结构都是这样的:而在实际的应用中,绝大多数会出

zeroMQ初体验-9.优雅的扩展(代理模式)
前面所谈到的网络拓扑结构都是这样的:


而在实际的应用中,绝大多数会出现这样的结构要求:


zeroMQ中自然也提供了这样的需求案例:

1.发布/订阅 代理模式:

import zmqcontext = zmq.Context()frontend = context.socket(zmq.SUB)frontend.connect("tcp://192.168.55.210:5556")backend = context.socket(zmq.PUB)backend.bind("tcp://10.1.1.0:8100")frontend.setsockopt(zmq.SUBSCRIBE, '')while True:    while True:        message = frontend.recv()        more = frontend.getsockopt(zmq.RCVMORE)        if more:            backend.send(message, zmq.SNDMORE)        else:            backend.send(message)            break # Last message part

注意代码,这个代理是支持大数据多包发送的。这个proxy实现了下图:


2.请求/答复 代理模式:
因为zeroMQ天然支持"多对多",所以看似不需要代理啊,如下图:


不过,这样会有一个问题,客户端需要知道所有的服务地址,并且在服务地址出现变迁时,需要通知客户端,这样迁移扩展的复杂度将无法预估。故,需要实现下图:

客户端:
import zmqcontext = zmq.Context()socket = context.socket(zmq.REQ)socket.connect("tcp://localhost:5559")for request in range(1,10):    socket.send("Hello")    message = socket.recv()    print "Received reply ", request, "[", message, "]"


服务器端:
import zmqcontext = zmq.Context()socket = context.socket(zmq.REP)socket.connect("tcp://localhost:5560")while True:    message = socket.recv()    print "Received request: ", message    socket.send("World")


代理端:
import zmqcontext = zmq.Context()frontend = context.socket(zmq.XREP)backend = context.socket(zmq.XREQ)frontend.bind("tcp://*:5559")backend.bind("tcp://*:5560")poller = zmq.Poller()poller.register(frontend, zmq.POLLIN)poller.register(backend, zmq.POLLIN)while True:    socks = dict(poller.poll())    if socks.get(frontend) == zmq.POLLIN:        message = frontend.recv()        more = frontend.getsockopt(zmq.RCVMORE)        if more:            backend.send(message, zmq.SNDMORE)        else:            backend.send(message)    if socks.get(backend) == zmq.POLLIN:        message = backend.recv()        more = backend.getsockopt(zmq.RCVMORE)        if more:            frontend.send(message, zmq.SNDMORE)        else:            frontend.send(message)

上面的代码组成了下面的网络结构:


客户端与服务器端互相透明,世界一下清净了...

这节上了好多图和代码,绝对都是干货。不过,既然0mq已经想到了,为毛还要咱自己写代理捏?So,虽然上面的都是干货,或许,马上,就可以统统忘掉了。下面,展示下0mq自带的代理方案:
import zmqdef main():        context = zmq.Context(1)        frontend = context.socket(zmq.XREP)    frontend.bind("tcp://*:5559")        backend  = context.socket(zmq.XREQ)    backend.bind("tcp://*:5560")        zmq.device(zmq.QUEUE, frontend, backend)        frontend.close()    backend.close()    context.term()    if __name__ == "__main__":    main()

这是应答模式的代理,官方提供了三种标准代理:
应答模式:queue XREP/XREQ
订阅模式:forwarder SUB/PUB
分包模式:streamer PULL/PUSH

特别提醒:
官方可不推荐代理混搭,不然责任自负。按照官方的说法,既然要混搭,还是自个儿写代理比较靠谱~

(未完待续) 1 楼 guozhiwei 2011-12-16   请问下 代理模式的 代理结点的  单点问题怎么能很好的解决呢 2 楼 iyuan 2011-12-16   guozhiwei 写道请问下 代理模式的 代理结点的  单点问题怎么能很好的解决呢
通常的场景是:proxy-a:1,2;proxy-b:1,2。全局上看代理就可以避免单点,不过局部点对于使用proxy-a的client而言,代理仍然是唯一单点的.从纯逻辑的角度来讲,只能从client端入手解决代理单点,即绑定多个代理地址(前提是不需要担心client知道的太多~)。
具体方案的选择要看具体业务及运营的情况,并不存在什么万能法门。

热点排行