首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我可以异步复制webapp2.RequestHandler请求到不同的url吗?

我可以异步复制webapp2.RequestHandler请求到不同的url吗?
EN

Stack Overflow用户
提问于 2016-08-06 00:55:39
回答 1查看 317关注 0票数 3

对于一定百分比的生产流量,我希望将接收到的请求复制到不同版本的应用程序中。这需要异步进行,这样我就不会对客户端的服务时间增加一倍。

这样做的原因是,我可以比较prod版本和生产候选版本生成的响应。如果他们的结果有适当的相似之处,我可以相信新版本并没有破坏任何东西。(如果我对应用程序进行了功能更改,我将从这个比较中筛选出响应的必要部分。)

所以我想找一个相当于:

代码语言:javascript
复制
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 caller

UPDATE google.appengine.api.urlfetch被认为是解决我的问题的一种可能的解决方案,但是它在dev_appserver中是同步的,尽管它的行为符合我在生产中所希望的方式(在调用get_response()并阻止它之前,请求不会发出)。:

代码语言:javascript
复制
    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.46627306938

UPDATE2

因此,在使用了一些其他选项之后,我找到了一种完全非阻塞请求的方法:

代码语言:javascript
复制
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中不起作用。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-06 03:29:10

URL提取服务支持异步请求。来自发出异步请求

默认情况下,HTTP(S)请求是同步的。要发出异步请求,应用程序必须:

  1. 使用rpc()创建一个新的RPC对象。此对象表示后续方法调用中的异步调用。
  2. 调用呼叫()发出请求。此方法以RPC对象和请求目标的URL作为参数。
  3. 调用RPC对象的结果()方法。如果请求成功,此方法将返回结果对象,并在请求期间发生错误时引发异常。

下面的片段演示如何从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上时,它们就会这样做。就我个人而言,我还没有使用异步调用,所以我不能说。

如果意图完全不是阻止,而是等待生产候选应用程序的响应,您可以在任务队列上推送原始请求和生产准备响应的副本,然后回答原始请求--延迟为零(加入任务队列的响应)。

在原始请求的关键路径之外,相应任务队列的处理程序将使用原始请求的副本(异步与否,从影响生产应用程序响应时间的角度来看并不重要)向暂存应用程序发出请求,获取其响应并将其与生产--准备好的响应、记录三角洲等进行比较。这可以很好地封装在单独的模块中,对生产应用程序进行最小的更改,并根据需要部署/删除。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38799566

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档