【发布时间】:2013-08-24 07:57:18
【问题描述】:
在这种情况下,必须将并行性引入后端服务器。
我愿意查询 N 个 ELB,每个查询 5 个不同的查询,并将结果发送回 Web 客户端。
后端是Tornado,根据我在docs看过很多遍,以前用@gen.Task或者gen.coroutine应该可以并行处理好几个任务。
但是,我必须在这里遗漏一些东西,因为我所有的请求(20 个,4 个 elbs * 5 个查询)都是一个接一个地处理的。
def query_elb(fn, region, elb_name, period, callback):
callback(fn (region, elb_name, period))
class DashboardELBHandler(RequestHandler):
@tornado.gen.coroutine
def get_elb_info(self, region, elb_name, period):
elbReq = yield gen.Task(query_elb, ELBSumRequest, region, elb_name, period)
elb2XX = yield gen.Task(query_elb, ELBBackend2XX, region, elb_name, period)
elb3XX = yield gen.Task(query_elb, ELBBackend3XX, region, elb_name, period)
elb4XX = yield gen.Task(query_elb, ELBBackend4XX, region, elb_name, period)
elb5XX = yield gen.Task(query_elb, ELBBackend5XX, region, elb_name, period)
raise tornado.gen.Return(
[
elbReq,
elb2XX,
elb3XX,
elb4XX,
elb5XX,
]
)
@tornado.web.authenticated
@tornado.web.asynchronous
@tornado.gen.coroutine
def post(self):
ret = []
period = self.get_argument("period", "5m")
cloud_deployment = db.foo.bar.baz()
for region, deployment in cloud_deployment.iteritems():
elb_name = deployment["elb"][0]
res = yield self.get_elb_info(region, elb_name, period)
ret.append(res)
self.push_json(ret)
def ELBQuery(region, elb_name, range_name, metric, statistic, unit):
dimensions = { u"LoadBalancerName": [elb_name] }
(start_stop , period) = calc_range(range_name)
cw = boto.ec2.cloudwatch.connect_to_region(region)
data_points = cw.get_metric_statistics( period, start, stop,
metric, "AWS/ELB", statistic, dimensions, unit)
return data_points
ELBSumRequest = lambda region, elb_name, range_name : ELBQuery(region, elb_name, range_name, "RequestCount", "Sum", "Count")
ELBLatency = lambda region, elb_name, range_name : ELBQuery(region, elb_name, range_name, "Latency", "Average", "Seconds")
ELBBackend2XX = lambda region, elb_name, range_name : ELBQuery(region, elb_name, range_name, "HTTPCode_Backend_2XX", "Sum", "Count")
ELBBackend3XX = lambda region, elb_name, range_name : ELBQuery(region, elb_name, range_name, "HTTPCode_Backend_3XX", "Sum", "Count")
ELBBackend4XX = lambda region, elb_name, range_name : ELBQuery(region, elb_name, range_name, "HTTPCode_Backend_4XX", "Sum", "Count")
ELBBackend5XX = lambda region, elb_name, range_name : ELBQuery(region, elb_name, range_name, "HTTPCode_Backend_5XX", "Sum", "Count")
【问题讨论】:
-
如果
ELBSumRequest和朋友自己阻塞函数而不是产生协程,Tornado 就无法交错它们。如果你不能重写它们(或者把它们分解成更小的部分,这样每个部分都让给下一个部分,这让调度程序有机会进入中间),协同程序在这里帮不了你;你将不得不使用线程(或通过monkeypatching阻塞调用使用准抢先式greenlets,但Tornado支持前者而不支持后者,我怀疑你想重写gevent中的所有内容或任何东西......)。跨度> -
@abarnert,刚刚添加了实现。您能否提供帮助并建议如何以异步方式重写
ELBQuery?
标签: python parallel-processing tornado future coroutine