Google App Engine 的 URL Fetch 在生产环境不工作
我正在使用谷歌应用引擎的urlfetch功能,想要远程登录到另一个网络服务。在开发环境中一切正常,但当我切换到生产环境时,登录过程就失败了。你有什么建议可以帮助我调试生产环境中的URL fetch吗?
我在URL fetch中使用了cookies和其他头信息(我手动在头信息中设置了cookies)。其中一个cookie是会话cookie。
在生产环境中没有错误或异常。当我向URL发送登录请求时,返回了会话cookies,但当我使用这些会话cookies请求页面时,它们被忽略了,系统又要求我输入登录信息。在开发环境中,一旦获得会话cookies,就可以顺利访问内部页面。我原以为问题出在保存cookies上,但它们看起来是正确的,因为请求几乎是一样的。
这是我调用的方式:
fetchresp = urlfetch.fetch(url=req.get_full_url(),
payload=req.get_data(),
method=method,
headers=all_headers,
allow_truncated=False,
follow_redirects=False,
deadline=10
)
以下是我对问题的一些猜测:
- 谷歌的url fetch实现方式可能因为分布式的特性而导致问题。
- 在生产环境中,头信息的发送顺序可能与开发环境不同,可能让服务器感到困惑。
- 目标服务器可能将一些谷歌的服务器列入黑名单。
以下是我排除的一些假设:
- 谷歌的缓存太过激进。但我在使用头信息Cache-Control: no-store关闭缓存后,问题依然存在。
- 谷歌的urlfetch速度太快,导致目标服务器无法处理。但我在请求之间插入延迟后,问题仍然存在。
- 谷歌在User-Agent头中附加了一些数据。但我在开发环境中添加了这个头信息,问题依然没有出现。
生产环境的URL fetch和开发环境的URL fetch之间还有什么其他不同之处吗?你有什么调试的想法吗?
更新 2
(第一次更新已包含在上面)我不知道是不是我做了什么(也许是上面提到的添加延迟或禁用缓存),但现在生产环境大约有50%的时间可以正常工作。这看起来确实像是一个竞争条件。不幸的是,我不知道问题出在我的代码、谷歌的代码,还是目标服务器的代码上。
3 个回答
我在做一个网页应用时遇到了类似的问题。当我查看urlfetch的文档时,发现进行数据请求时,最大超时时间是60秒,但默认设置只有5秒。
在我本地的机器上,5秒足够用来请求网址,但在谷歌的应用引擎(GAE)上,只有大约20%的情况下能在5秒内完成任务。
我加上了参数deadline=60
,从那以后就一直正常工作了。
希望这对其他人有帮助!
查看一下你服务器的日志,看看是否有 GAE 把某些头信息给删掉了。我发现 GAE(我觉得在开发服务器上也见过)会把它不喜欢的头信息给去掉。
根据你调用的网络服务,GAE 可能对它的接受程度没有你本地机器那么高。
正如其他人提到的,开发环境(dev)和生产环境(prod)之间的主要区别在于来源IP和一些请求头的处理方式。你可以在这里查看受限头部的列表。我不确定这是否有文档说明,但在生产环境中,你的应用ID会被加到用户代理的末尾。我曾经遇到过一个问题,在生产环境中请求被识别为搜索引擎爬虫,因为我的应用ID里包含了“bot”这个字符串。
你提到你手动设置了cookies,包括会话cookie。这是否意味着你在开发环境中建立了一个会话,然后想在生产环境中重用它?有可能远程服务器在记录建立会话的源IP,并要求后续请求必须来自同一个IP吗?
你说它不工作,但没有抛出异常。这具体是什么意思呢?你是收到了HTTP 200状态码,但响应体是空的吗?还是其他的HTTP状态码?你最好的办法可能是联系远程服务的拥有者,看看他们能否更具体地告诉你请求出了什么问题。其他的猜测都不太靠谱。