백엔드 서버로 병렬 처리를 가져와야하는 경우를 생각해보십시오.토네이도 gen.Task/gen.coroutine 데코레이터를 사용하여 병렬 처리를 수행하는 방법
5 개의 서로 다른 쿼리에 대해 N ELB를 쿼리하고 웹 클라이언트에 결과를 다시 보냅니다.
백엔드는 토네이도입니다. 이전에 docs에서 여러 번 읽은 바에 따르면, @ genTask 또는 gen.coroutine을 사용하면 과거에 여러 작업을 병렬로 처리 할 수있게되었습니다.
그러나 내 모든 요청 (20 자리 숫자, 4 엘브 * 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'와 친구들이 coroutine을 만드는 대신 함수를 차단하고 있다면, 토네이도가 인터리브 할 수있는 방법이 없습니다.그것들을 다시 쓸 수 없다면 (또는 작은 조각으로 나눠서 각자가 다음에 내놓을 수있게되면, 스케줄러에게 중간에 들어갈 기회가 주어집니다), 코 루틴은 여기 당신을 도울 수 없습니다; 당신은 스레드를 사용해야합니다 (또는 호출 차단 monkeypatching에 의해 준 선제 적 그린 레트를 사용해야합니다. 그러나 토네이도는 후자를 위해서가 아니라 후자를 위해 지원합니다. 그리고 나는 당신이'gevent' 또는 무엇이든 모든 것을 다시 쓰길 원합니다.). – abarnert
@abarnert, 방금 구현을 추가했습니다. ELBQuery를 비동기식으로 재 작성하는 방법을 돕고 제안 해 주시겠습니까? –