我们的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以查找作业状态时看到错误,而很少在数据获取时看到错误。当我们重新运行操作时,系统会工作。
知道为什么会发生这种情况并且 - 或许 - 这是处理它的最佳做法吗?
答案 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在这个网站上超时和截止日期的问题有很多问题,所以如果你遇到奇怪的事情,我不会感到惊讶。
祝你好运!