需求是有消息源,需要分不同的topic,然后中间处理逻辑分别处理各自的topic,最后有个总收集器把各个中间处理的结果再处理一下,形成最终结果。消息源是java的API,中间处理逻辑是python写的,然后收集器逻辑是java。
目前的方式是用redis的list队列,不同的topic分布到不同的list队列中,这当然是不好的,因为一个topic对应于一个中间处理逻辑,假如再扩展的话,就要更改消息源的程序。自然,redis和zeromq都有广播机制可以使用。准备从消息源到中间处理逻辑这块会按照zeromq的广播机制来处理。可以自由扩展中间处理逻辑的个数。
另一段是从中间处理到收集器,要求是具备负载均衡的,假如有多个收集器的话,这多个收集器之间是可以负载均衡的。
思路一是多个中间逻辑处理的结果都放入到一个redis的list中,然后下游的多个收集器都读取这同一个list的数据。这种方式比较粗暴。
思路二是利用zeromq的pullpush实现的负载均衡。
server部分的代码,注意要bind
import zmq
import time
c = zmq.Context()
s = c.socket(zmq.PUSH)
s.bind("tcp://*:8990")
for e in [1,2,3,4,5,6,7,8,9,0,10]:
e = str(e)
time.sleep(1)
s.send_string(e)
client部分的代码,注意要connect
import zmq
c = zmq.Context()
s = c.socket(zmq.PULL)
s.connect("tcp://localhost:8990")
while True:
msg = s.recv_string()
print(msg)
client部分分出两个进程,实现两个client连接一个server
而我们这里的server会有多个而不是一个,本身server又是订阅的客户端sub,如图所示
pub server部分代码
import time
import zmq
def main():
all_topics = ["aaafffff111","aaannnn222","aaabcccc333","ccc444","eee555"]
ctx = zmq.Context()
s = ctx.socket(zmq.PUB)
s.bind("tcp://*:5555")
for topic in all_topics:
time.sleep(1)
print(topic)
s.send_string(topic)
print("--------------")
if __name__ == '__main__':
main()
sub client and push client 注意push是connect
import zmq
ctx = zmq.Context()
sock = ctx.socket(zmq.SUB)
sock.setsockopt_string(zmq.SUBSCRIBE, "aaa")
sock.connect('tcp://localhost:5555')
sender = ctx.socket(zmq.PUSH)
sender.connect('tcp://127.0.0.1:5558')
while True:
msg = sock.recv_string()
if msg:
print(msg)
sender.send_string(msg)
pull server部分的代码 注意 bind
import zmq
context = zmq.Context()
recive = context.socket(zmq.PULL)
recive.bind('tcp://127.0.0.1:5558')
while True:
data = recive.recv_string()
print(data)