Introduction: ZEROMQ Middleware, he is a lightweight message middleware, legend is the world's fastest message middleware, why do you say so? Because the general message middleware need to start the message server, but zeromq this guy altogether no message server, he has no message middleware shelves, but this does not cover his strong. By contrast with the ACTIVEMQ,RABBITMQ, it is clear that the function is not as strong as the previous two, he does not support the persistence of messages, but there is the message copy feature, he does not support crash recovery, and because he is too fast, the client may not have started, the service side of the message has been sent out, This is easy to lose the news, but Zeromq free his way, first said so much. Let's take a look at how to introduce this powerful tool into Python. My own reason, learning to understand, the main reason is to understand the practice of the application of the principle and logic, it is best to perceive the design of the idea, for the future, to do something to accumulate some experience. Also recently more attention to automation operations of some things. Online says Saltstack itself is using the ZEROMQ to do Message Queuing. That's why I'm interested. Install: My OS is ubuntu 14.04 python zeromq Environment installation Reference under the official website Face test: One, C/s mode: Server-side code: #!/usr/bin/env Python # Coding:utf8 #author: [email protected] Import ZMQ #调用zmq相关类方法, bonding port context = zmq. Context () socket = Context.socket (ZMQ. REP) socket.bind (' tcp://*:10001 ') while True: #循环接受客户端发来的消息 msg = SOCKET.RECV () Print "Msg info:%s"%msg #向客户端服务器发端需要执行的命令 cmd_info = raw_input ("Client cmd info:"). Strip () Socket.send (Cmd_info) Socket.close () client-side code: Import ZMQ Import time import Commands context = Zmq. Context () socket = Context.socket (ZMQ. REQ) socket.connect (' tcp://127.0.0.1:10001 ') def execut_cmd (cmd): s,v = Commands.getstatusoutput ( CMD) return v while True: #获取当前时间 now_time = Time.strftime ("%y-%m-%d%h:%m:%s", Tim E.localtime ()) Socket.send ("Now time info:[%s" request execution command: ' \ n ',%s "% (Now_time,result)) Recov_msg = Socket.recv () #调用execut_cmd函数, executes the command sent over by the server result = Execut_cmd (recov_msg) PRI NT Recov_msg, ' \ n ', result, time.sleep (1) #print "Now time info:%s cmd status:[%s],result:[%s]"% (now_ TIME,S,V) Continue Socket.close () Note: This mode is classic answer mode, cannot send multiple data at the same time, this mode is mainly used for remote call and task assignment, but I am stupid, or understand There's time in the back. Test: Req End # Python zmq-server-cs-v01.py Rep-side # python zmq-client-cs-v01.py Two, publish subscription mode (PUB/SUB) pub publisher code is as follows: #!/usr/bin/env python # Coding:utf8 #author: [email protected] Import itertools import sys,time,zmq def main (): if Le N (sys.argv)! = 2:print ' Usage:publisher ' sys.exit (1) bind_to = sys.argv[1] All_topics = [' sports.general ', ' sports.football ', ' sports.basketball ', ' stocks.general ', ' stocks '. GOOG ', ' stocks. AAPL ', ' weather '] ctx = zmq. Context () s = Ctx.socket (ZMQ. PUB) S.bind (bind_to) print "Starting broadcast on topics:" Print "%s"%all_topics Print "Hit Ctrl-c to stop broadcasting." Print "Waiting so subscriber sockets can connect ..." Print time.sleep (1) msg_counter = i Tertools.count () try:for topic in Itertools.cycle (all_topics): Msg_body = str (ms G_counter.next ()) #print msg_body, print ' topic:%s,msg:%s '% (topic,msg_body) S.send_multipart ([t Opic,msg_body]) #s. Send_pyobj ([topic,msg_body]) Time.sleep (0.1) except Keyboardin Terrupt:pass print "wating for message queues to flush" time.sleep (0.5) s . Close () print "Done" if __name__ = = "__main__": Main () sub-port code: #!/usr/bin/en V Python # Coding:utf8 #author: [email protected] Import ZMQ import time, SYS def main (): If Len (SYS.ARGV) < 2:print "Usage:subscriber [topic topic]" Sys.exit (1) connect_to = sys.argv[1] topics = sys.argv[2:] ctx = zmq. Context () s = Ctx.socket (ZMQ. SUB) S.connect (connect_to) #manage subscriptions if not topics:priNT "receiving messages on all topics ..." s.setsockopt (ZMQ. SUBSCRIBE, ') Else:print "receiving messages on topics:%s ..."%topics for T in Topics:s.setsockopt (ZMQ. subscribe,t) Print Try:while true:topics,msg = S.recv_multipart ( ) print ' topic:%s,msg:%s '% (topics,msg) except Keyboardinterrupt:pass Print "Done ..." if __name__ = = "__main__": Main () Note: The Publish and subscribe roles here are absolute, that is, publishers cannot use recv, Subscribers cannot use S End, the official website also provides a possible problem: when subscribers consume slower than the release, there will be a build-up of data, but also in the publishing side of the accumulation (some friends point out that is stacked on the consumer side, perhaps the new version of the improvement, need the reader's attempt and feedback, thx!), obviously, this is not acceptable. As for the solution, maybe the following "Divide and conquer" is it? Test: Pub end: Publisher #python zmq-server-pubsub-v02.py tcp://127.0.0.1:10001 Sub-terminal: Subscriber #python zmq-server-cs-v01.py tcp://127.0.0.1:10001 Sports.football Three, push/pull divide and conquer mode. Task Publisher Code #!/usr/bin/env python # CodinG:utf8 #author: [email protected] Import ZMQ Import random import time context = Z Mq. Context () #socket to send messages on sender = Context.socket (ZMQ. PUSH) sender.bind (' tcp://*:5557 ') print ' press Enter when the workers is ready: ' _ = Raw_input () Print "Sending tasks to workers ..." #The first messages is "0" and Signals start to batch sender.send (' 0 ') #Initialize random mumber generator Random.seed () #send Tasks total_msec = 0 fo R TASK_NBR in range: #Random workload from 1 to msecs #print TASK_NBR, workload = Random.randint (1,100) total_msec + = Workload Sender.send (str (workload)) print "Total ex" pected cost:%s msec:%s workload:%s "% (total_msec,task_nbr,workload) work-side code is as follows: #!/usr/bin/env python # Coding:utf8 #author: [email protected] ImpORT SYS,TIME,ZMQ Import Commands context = Zmq. Context () #socket to receive messages on receiver = Context.socket (ZMQ. Pull) receiver.connect (' tcp://127.0.0.1:5557 ') #Socket to send messages to Sender = Context.socket (ZM Q.push) Sender.connect ("tcp://127.0.0.1:5558") #Process tasks forever while true:s = Rece IVER.RECV () #Simple progress indicator for the viewer print S, sys.stdout.write ("%s ' \ t ' %s) Sys.stdout.flush () #Do the work time.sleep (int (s) *0.001) #Send results to Sink Sender.send (s) pull-end code is as follows: #!/usr/bin/env python # Coding:utf8 #author : [email protected] Import sys import time import zmq context = Zmq. Context () #Socket to receive messages on receiver = Context.socket (ZMQ. Pull) receiver.bind ("TCp://*:5558 ") #Wait for start of the batch S = receiver.recv () #Start Our clock now Tstart = Time.time () #Process confirmations total_msec = 0 for TASK_NBR in range (100 ): s = receiver.recv () if task_nbr% = = 0:print Task_nbr, print S, Sys.stdout.write (': ') else:print S, #print TASK_NBR, Sys.stdout.write ('. ') #Calculate and report duration of batch tend = time.time () print "Total elapsed time:%d msec"% ((Ten D-tstart) *1000 Note: This mode is the same as the pub/sub mode, the difference is two points: 1, the mode in the absence of consumers, the publisher's information is not consumed (by the publisher process maintenance) 2, multiple consumers consume the same column of information, assuming a Get a message, B will no longer get this model is mainly aimed at the consumer capacity is not enough, the provision of multi-consumer parallel consumption solution (also considered as the previous pub/sub model of the "blockage problem" of a solution strategy bar) in fact, the so-called point is the pull end to rob the push side issued by any Who is to be counted. Test: #python zmq-server-pushpull-v03.py #python zmq-work-pushpull-v03.py #python zmq-client-pushpull-v03.py
One of the Python ZEROMQ Learning series for network programming