0

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

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

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

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

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

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

我对并发编程或异步编程相当陌生,所以在这里会重视任何输入。解决这个问题的“最佳”方法是什么?

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

干杯,维克多

4

2 回答 2

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 将允许您异步执行网络绑定工作,这意味着您的代码不会忙于等待网络连接,而是让操作系统在收到数据时通知它。
  • 这是个人喜好,但我认为这gevent你想做一次性工作时最容易使用的异步库。(例如,您不必开始reactora-la twisted)。

它会起作用吗?

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

于 2012-12-20T11:56:06.223 回答
0

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

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

现在计算输入变量(主机名)的列表,并使用multiprocessing.Pool.map()multiprocessing.Pool.map_async()并行执行函数。该async变体将更快地开始返回数据,但您可以在回调中执行的工作量是有限的。

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

但是,如果存在网络延迟,python 程序对此无能为力。

于 2012-12-20T11:53:30.470 回答