与BigQuery通信时,GAE App会出现套接字错误

时间:2015-05-06 10:32:58

标签: google-app-engine google-bigquery google-api-python-client

我们的GAE python应用程序使用Google Api Client for Python(目前我们使用版本 1.3.1 )与GAE特定的身份验证帮助程序与BigQuery进行通信。我们经常在与BigQuery通信时遇到套接字错误。

更具体地说,我们按如下方式构建了一个python Google API客户端

1. bq_scope = 'https://www.googleapis.com/auth/bigquery'
2. credentials = AppAssertionCredentials(scope=bq_scope)
3. http = credentials.authorize(httplib2.Http())
4. bq_service = build('bigquery', 'v2', http=http)

然后我们与BQ服务进行交互并获得以下错误

  

文件“/base/data/home/runtimes/python27/python27_dist/lib/python2.7/gae_override/httplib.py”,第536行,在getresponse中       '连接到服务器时出错:%s'%e)   错误:连接到服务器时出错:无法获取URL:[api url ...]

引发的错误类型为 google.appengine.api.remote_socket._remote_socket_error.error ,而不是包装错误的异常。

最初我们认为它可能与超时有关,所以我们也尝试在上面的代码段中设置超时更改第3行

3. http = credentials.authorize(httplib2.Http(timeout=60))

但是,根据客户端库的日志输出,API调用崩溃时间不到1秒,显式设置超时并未改变系统行为。

请注意,错误发生在各种API调用中,而不仅仅是单个API调用中,并且通常会在非常轻的操作中发生,例如,我们经常在轮询BQ以查找作业状态时看到错误,而很少在数据获取时看到错误。当我们重新运行操作时,系统会工作。

知道为什么会发生这种情况并且 - 或许 - 这是处理它的最佳做法吗?

1 个答案:

答案 0 :(得分:0)

所有HTTP(s)请求都将通过urlfetch服务进行路由。

在此之下,Google Api Client for Python使用httplib2发出HTTP请求,并且这个库使用套接字。

由于错误来自套接字,您可能会尝试在那里设置超时。

import socket
timeout = 30
socket.setdefaulttimeout(timeout)

如果我们继续向上堆栈,httplib2将使用套接字级别超时的timeout参数。

http://httplib2.readthedocs.io/en/latest/libhttplib2.html

进一步向上移动堆栈可以设置BigQuery的超时和重试次数。

try:
    timeout = 30000
    num_retries = 5
    query_request = bigquery_service.jobs()
    query_data = {
        'query': (query_var),
        'timeoutMs': timeout,
    }

最后你可以设置urlfetch的超时时间。

from google.appengine.api import urlfetch
urlfetch.set_default_fetch_deadline(30)

如果您认为超时相关,则可能需要测试每个库/级别以确保正确传递超时。您还可以使用基本计时器查看结果。

start_query = time.time()
query_response = query_request.query(
projectId='<project_name>',
body=query_data).execute(num_retries=num_retries)
end_query = time.time()
logging.info(end_query - start_query)

关于GAE和BigQuery在这个网站上超时和截止日期的问题有很多问题,所以如果你遇到奇怪的事情,我不会感到惊讶。

祝你好运!