Python - 通过WAN链接查询/控制多个主机?

时间:2012-12-20 11:42:46

标签: python twisted celery tornado

我们在多个国家(日本,香港,新加坡等)设有多个数据中心。

我们在每个位置的多个主机上运行应用程序 - 总共大约50-100个主机。

我正在研究一个Python脚本,该脚本查询每个应用程序的状态,向它们发送各种触发器,并在运行时从它们中检索其他内容。这个脚本可以想象地查询中央服务器,然后中央服务器将请求发送到在每个主机上运行的代理。

其中一个要求是脚本尽可能具有响应性 - 例如如果我在所有位置的所有主机上查询应用程序的状态,我希望结果在1-3秒内,而不是20-30秒。

因此,按顺序查询每个主机的速度太慢,特别是考虑到我们需要进行的广域网跃点。

我们可以假设每个主机本身的查询相当简单(例如是否正在运行进程)。

我对并发编程或异步编程相当新,所以在这里根本不重视任何输入。什么是最好的"解决这个问题的方法是什么?

  • 使用多线程或多进程方法 - 例如为每个主机生成一个新线程,将它们全部发送出去,然后等待回复?
  • 使用asyncore,twisted,tornado - 任何适用于此的评论? (我得到的印象是,asyncore不是那么受欢迎。龙卷风可能很有趣,但不确定如何在这里使用?)
  • 使用某种消息队列(例如Kombu / RabbitMQ)?
  • 以某种方式使用芹菜?对于我们想要的响应时间,它是否足够响应? (例如,上述情况下不到3秒)。

干杯, 维克多

2 个答案:

答案 0 :(得分:1)

使用gevent

如何?

from gevent import monkey; monkey.patch_socket() # So anything socket-based now works asynchronously. 
#This should be the first line of you code!
import gevent

def query_server(server_ip):
    # do_something with server_ip and sockets

server_ips = [....]
jobs = [gevent.spawn(query_server, server_ip) for server_ip in server_ips]
gevent.joinall(jobs)
print [job.result for job in jobs]

为什么要这么麻烦?

  • 您的所有代码都将在单个进程和单个线程中运行。这意味着您不必担心锁,信号量和消息传递。
  • 您的任务似乎主要是网络限制的。 Gevent将让您以异步方式进行网络绑定工作,这意味着您的代码不会忙于等待网络连接,而是让OS在收到数据时通知它。
  • 这是个人偏好,但我认为gevent是您想要进行一次性工作时最容易使用的异步库。 (例如,您不必开始reactor a-la twisted)。

会起作用吗?

响应时间将是您最慢的服务器的响应时间 如果使用gevent没有这样做,那么您将不得不修复您的网络。

答案 1 :(得分:0)

使用multiprocessing.Pool,尤其是map()map_async()成员。

编写一个带有单个参数的函数(例如主机名,或者主机名和其他数据的列表/元组。让该函数查询主机并返回相关数据。

现在编译输入变量(主机名)列表,并使用multiprocessing.Pool.map()multiprocessing.Pool.map_async()并行执行这些功能。 async变体将尽快开始返回数据,但您在回调中可以完成的工作量有限。

这将自动使用与您的机器一样多的内核来并行处理这些功能。

如果有网络延迟,那么python程序可以做的很少。