需求是有消息源,需要分不同的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)