某些AWS实例上的Google c2dm transient 401错误

我们怎样才能知道为什么当我们要求c2dm发送通知时,在某些AWS实例上, Google c2dm推送服务偶尔出现了401错误?

这是一个短暂的问题。 所有AWS实例在向Google c2dm发送HTTPS请求方面大都成功,有些实例100%成功,有些实例偶尔会获得401。 所以我们不认为这是我们的c2dm注册或我们的通知代码(python)已经生产了一年多的问题。 401错误从2012年5月16日开始。

相反,我们认为亚马逊基础架构中的某些东西,包括DNScaching,可能会以某种方式涉及到这个问题。 Google善意地回答我们的询问:

我会寻找可能导致片状交stream的东西。 尝试看看是否在该机器的networking适配器上获得exception数量的损坏或丢弃的数据包。

但是,我们没有看到任何“片面交stream”的证据。 发生问题时,实例上的CPU负载几乎为0,麻烦的机器上的以太网连接的数量平均低于没有问题的实例。

一个线索是401错误似乎发生在一个丛中(几个发生在大约4分钟之内),并且这个丛往往间隔10到60分钟(虽然可以有许多小时没有错误)。 我们没有看到I / O错误或“flaky通信”错误,只有来自Google c2dm的401错误。

一个serverfault post使我们想到了AWS上的DNScaching,因为它涉及到Google c2dm服务提供的证书中的主机名的SSLvalidation,但是似乎我们使用的python 2.7 urllib2并没有通过validation主机默认。

另一个线索是,我们使用“弹性IP”function更改了第一个显示问题的Web实例的IP地址:同一个持续运行的实例,只是一个新的IP。 这个例子在4天里成功了100%,但是现在又回到了偶尔的401s。

我们能做些什么来揭示这一点?

堆栈跟踪示例:

c2dm push error: HTTP Error 401: Unauthorized Traceback (most recent call last): File "/home/django/base/src/mmsite/push/models.py", line 262, in send_c2dm_message response = urllib2.urlopen(request) # third try File "/usr/local/lib/python2.7/urllib2.py", line 126, in urlopen return _opener.open(url, data, timeout) File "/usr/local/lib/python2.7/urllib2.py", line 400, in open response = meth(req, response) File "/usr/local/lib/python2.7/urllib2.py", line 513, in http_response 'http', request, response, code, msg, hdrs) File "/usr/local/lib/python2.7/urllib2.py", line 438, in error return self._call_chain(*args) File "/usr/local/lib/python2.7/urllib2.py", line 372, in _call_chain result = func(*args) File "/usr/local/lib/python2.7/urllib2.py", line 521, in http_error_default raise HTTPError(req.get_full_url(), code, msg, hdrs, fp) HTTPError: HTTP Error 401: Unauthorized 

401回复中返回HTTP头示例:

 'headers': [ 'Content-Type: text/html; charset=UTF-8\r\n', 'Date: Fri, 25 May 2012 00:24:25 GMT\r\n', 'Expires: Fri, 25 May 2012 00:24:25 GMT\r\n', 'Cache-Control: private, max-age=0\r\n', 'X-Content-Type-Options: nosniff\r\n', 'X-Frame-Options: SAMEORIGIN\r\n', 'X-XSS-Protection: 1; mode=block\r\n', 'Server: GSE\r\n', 'Connection: close\r\n'] 

编辑其他testing信息:

我们能够在开发networking上重现这个瞬态401。 有时候它有效,有时达到了401个。由于开发networking与AWS完全分离,这就消除了我们考虑的所有AWSvariables,并且重视了这个问题在Google方面的理论。 谷歌善意地回答说,他们会升级这个问题。

这是通过更改auth密钥(一个通过URL请求到c2dm服务的自动化进程获得新密钥,然后立即将其放入我们的服务器端推送代码中)来解决的。 我们不情愿这样做,而关键是大多数c2dm推送工作正常,但它看起来像一些谷歌服务器不满意的关键,造成我们间歇性的错误。 自从一周前改变它以来,我们一直没有错误。