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

前面所谈到的网络拓扑结构都是这样的:
[img]http://github.com/imatix/zguide/raw/master/images/fig15.png[/img]

而在实际的应用中,绝大多数会出现这样的结构要求:
[img]http://github.com/imatix/zguide/raw/master/images/fig16.png[/img]

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

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

import zmq

context = 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实现了下图:
[img]http://github.com/imatix/zguide/raw/master/images/fig17.png[/img]

2.请求/答复 代理模式:
因为zeroMQ天然支持"多对多",所以看似不需要代理啊,如下图:
[img]http://github.com/imatix/zguide/raw/master/images/fig18.png[/img]

不过,这样会有一个问题,客户端需要知道所有的服务地址,并且在服务地址出现变迁时,需要通知客户端,这样迁移扩展的复杂度将无法预估。故,需要实现下图:
[img]http://github.com/imatix/zguide/raw/master/images/fig19.png[/img]
客户端:

import zmq

context = 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 zmq

context = 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 zmq

context = 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)


上面的代码组成了下面的网络结构:
[img]http://github.com/imatix/zguide/raw/master/images/fig20.png[/img]

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

这节上了好多图和代码,绝对都是干货。不过,既然0mq已经想到了,为毛还要咱自己写代理捏?So,虽然上面的都是干货,或许,马上,就可以统统忘掉了。下面,展示下0mq自带的代理方案:

import zmq

def 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

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

(未完待续)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值