对于一定百分比的生产流量,我希望将接收到的请求复制到不同版本的应用程序中。这需要异步进行,这样我就不会对客户端的服务时间增加一倍。
这样做的原因是,我可以比较prod版本和生产候选版本生成的响应。如果他们的结果有适当的相似之处,我可以相信新版本并没有破坏任何东西。(如果我对应用程序进行了功能更改,我将从这个比较中筛选出响应的必要部分。)
所以我想找一个相当于:
class Foo(webapp2.RequestHandler):
def post(self):
handle = make_async_call_to('http://other_service_endpoint.com/', self.request)
# process the user's request in the usual way
test_response = handle.get_response()
# compare the locally-prepared response and the remote one, and log
# the diffs
# return the locally-prepared response to the callerUPDATE google.appengine.api.urlfetch被认为是解决我的问题的一种可能的解决方案,但是它在dev_appserver中是同步的,尽管它的行为符合我在生产中所希望的方式(在调用get_response()并阻止它之前,请求不会发出)。:
start_time = time.time()
rpcs = []
print 'creating rpcs:'
for _ in xrange(3):
rpcs.append(urlfetch.create_rpc())
print time.time() - start_time
print 'making fetch calls:'
for rpc in rpcs:
urlfetch.make_fetch_call(rpc, 'http://httpbin.org/delay/3')
print time.time() - start_time
print 'getting results:'
for rpc in rpcs:
rpc.get_result()
print time.time() - start_time
creating rpcs:
9.51290130615e-05
0.000154972076416
0.000189065933228
making fetch calls:
0.00029993057251
0.000356912612915
0.000473976135254
getting results:
3.15417003632
6.31326603889
9.46627306938UPDATE2
因此,在使用了一些其他选项之后,我找到了一种完全非阻塞请求的方法:
start_time = time.time()
rpcs = []
logging.info('creating rpcs:')
for i in xrange(10):
rpc = urlfetch.create_rpc(deadline=30.0)
url = 'http://httpbin.org/delay/{}'.format(i)
urlfetch.make_fetch_call(rpc, url)
rpc.callback = create_callback(rpc, url)
rpcs.append(rpc)
logging.info(time.time() - start_time)
logging.info('getting results:')
while rpcs:
rpc = apiproxy_stub_map.UserRPC.wait_any(rpcs)
rpcs.remove(rpc)
logging.info(time.time() - start_time)...but要注意的重要一点是,urllib中的异步获取选项在dev_appserver中都不起作用。在发现这一点之后,我回到@DanCornilescu的解决方案中,发现它只在生产中正常工作,而在dev_appserver中不起作用。
发布于 2016-08-06 03:29:10
URL提取服务支持异步请求。来自发出异步请求
默认情况下,HTTP(S)请求是同步的。要发出异步请求,应用程序必须:
下面的片段演示如何从Python应用程序发出基本的异步请求。首先,从导入urlfetch库:
从google.appengine.api导入urlfetch
接下来,使用urlfetch发出异步请求:
rpc = urlfetch.create_rpc() urlfetch.make_fetch_call(rpc,"http://www.google.com/") #.做其他事情..。try: result.status_code = result.status_code () == 200: text = result.content self.response.write(text) result.content: self.response.status_code =result.status_code logging.error(“错误生成RPC请求”),urlfetch.DownloadError: logging.error除外(“错误获取URL0")
注意:按照Sniggerfardimungus在问题的更新中提到的实验,异步调用在开发服务器上可能不像预期的那样工作--被序列化而不是并发,但是当部署在GAE上时,它们就会这样做。就我个人而言,我还没有使用异步调用,所以我不能说。
如果意图完全不是阻止,而是等待生产候选应用程序的响应,您可以在任务队列上推送原始请求和生产准备响应的副本,然后回答原始请求--延迟为零(加入任务队列的响应)。
在原始请求的关键路径之外,相应任务队列的处理程序将使用原始请求的副本(异步与否,从影响生产应用程序响应时间的角度来看并不重要)向暂存应用程序发出请求,获取其响应并将其与生产--准备好的响应、记录三角洲等进行比较。这可以很好地封装在单独的模块中,对生产应用程序进行最小的更改,并根据需要部署/删除。
https://stackoverflow.com/questions/38799566
复制相似问题