Google App Engine 的 URL Fetch 在生产环境不工作

4 投票
3 回答
1636 浏览
提问于 2025-04-17 07:10

我正在使用谷歌应用引擎的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 个回答

1

我在做一个网页应用时遇到了类似的问题。当我查看urlfetch的文档时,发现进行数据请求时,最大超时时间是60秒,但默认设置只有5秒。

在我本地的机器上,5秒足够用来请求网址,但在谷歌的应用引擎(GAE)上,只有大约20%的情况下能在5秒内完成任务。

我加上了参数deadline=60,从那以后就一直正常工作了。

希望这对其他人有帮助!

1

查看一下你服务器的日志,看看是否有 GAE 把某些头信息给删掉了。我发现 GAE(我觉得在开发服务器上也见过)会把它不喜欢的头信息给去掉。

根据你调用的网络服务,GAE 可能对它的接受程度没有你本地机器那么高。

2

正如其他人提到的,开发环境(dev)和生产环境(prod)之间的主要区别在于来源IP和一些请求头的处理方式。你可以在这里查看受限头部的列表。我不确定这是否有文档说明,但在生产环境中,你的应用ID会被加到用户代理的末尾。我曾经遇到过一个问题,在生产环境中请求被识别为搜索引擎爬虫,因为我的应用ID里包含了“bot”这个字符串。

你提到你手动设置了cookies,包括会话cookie。这是否意味着你在开发环境中建立了一个会话,然后想在生产环境中重用它?有可能远程服务器在记录建立会话的源IP,并要求后续请求必须来自同一个IP吗?

你说它不工作,但没有抛出异常。这具体是什么意思呢?你是收到了HTTP 200状态码,但响应体是空的吗?还是其他的HTTP状态码?你最好的办法可能是联系远程服务的拥有者,看看他们能否更具体地告诉你请求出了什么问题。其他的猜测都不太靠谱。

撰写回答