如果我們已經有一個通過Queue通信的多進程程序在同一臺機器上運行,現在,由於處理任務的進程任務繁重,希望把發送任務的進程和處理任務的進程分佈到兩臺機器上。怎麼用分佈式進程實現?原有的Queue可以繼續使用,但是,通過managers模塊把Queue通過網絡暴露出去,就可以讓其他機器的進程訪問Queue了。
Python的multiprocessing模塊不但支持多進程,其中managers子模塊還支持把多進程分佈到多臺機器上。一個服務進程可以作爲調度者,將任務分佈到其他多個進程中,依靠網絡通信。由於managers模塊封裝很好,不必瞭解網絡通信的細節,就可以很容易地編寫分佈式多進程程序。
首先編寫個manager服務器
import random, time, Queue
from multiprocessing.managers import BaseManager
task_queue = Queue.Queue()
result_queue = Queue.Queue()
def get_task_queue():
global task_queue
return task_queue
def get_result_queue():
global task_queue
return task_queue
def startManager(host, port, authkey):
BaseManager.register('get_task_queue', callable=get_task_queue)
BaseManager.register('get_result_queue', callable=get_result_queue)
manager = BaseManager(address=(host, port), authkey=authkey)
manager.start()
return manager
def put_queue(manager):
task = manager.get_task_queue()
while 1:
n = random.randint(0, 1000)
print ('Put task %d' % n)
task.put(n)
time.sleep(0.5)
if __name__ == "__main__":
host = '127.0.0.1'
port = 5000
authkey = 'abc'
manager = startManager(host, port, authkey)
put_queue(manager)
manager.shutdown
然後編寫worker
import random, time, Queue
from multiprocessing.managers import BaseManager
def start_worker(host, port, authkey):
BaseManager.register('get_task_queue')
BaseManager.register('get_result_queue')
print ('Connect to server %s' % host)
worker = BaseManager(address=(host, port), authkey=authkey)
worker.connect()
return worker
def get_queue(worker):
task = worker.get_task_queue()
result = worker.get_result_queue()
while 1:
if task.empty():
time.sleep(1)
continue
n = task.get(timeout=1)
print ('worker get %d' % n)
result.put(n)
time.sleep(1)
if __name__ == "__main__":
host = '127.0.0.1'
port = 5000
authkey = 'abc'
worker = start_worker(host, port, authkey)
get_queue(worker)
最後,先啓動manager服務器,然後啓動兩個worker
manager服務器截圖
worker1截圖
worker2截圖
可以看到worker1+worker2的數據了等於manager服務器的數據,並且沒有重複的值