Como podemos descobrir por que estamos recebendo erros 401 ocasionais do serviço de push Google c2dm em alguns < href="http://aws.amazon.com/"> AWS quando pede ao c2dm para entregar uma notificação?
Este é um problema transitório. Todas as instâncias da AWS são bem-sucedidas no envio de uma solicitação HTTPS para o Google c2dm, algumas ocorrências são bem-sucedidas em 100% do tempo e algumas obtêm 401 de vez em quando. Portanto, não acreditamos que isso seja um problema com nosso registro c2dm ou com nosso código de notificação (python) que está em produção há mais de um ano. Os erros 401 começaram em 16 de maio de 2012.
Em vez disso, estamos pensando que algo na infraestrutura da Amazon, incluindo o armazenamento em cache do DNS, pode de alguma forma estar envolvido no problema. O Google gentilmente respondeu à nossa pergunta dizendo:
I'd look for something that could cause flaky communications. Try and see if you're getting unusual numbers of corrupted or dropped packets on that machine's network
adapter.
No entanto, não vemos qualquer evidência de "comunicações escamosas". A carga da cpu nas instâncias é quase 0 quando os problemas ocorrem, e o número de conexões ethernet em máquinas problemáticas é, em média, menor do que em instâncias que não apresentam problemas.
Uma pista é que os erros 401 parecem ocorrer em uma moita (vários acontecendo dentro de cerca de 4 minutos um do outro), e que aglomerados são freqüentemente espaçados por 10 a 60 minutos (embora possa haver muitas horas sem erros) . Nós não vemos erros de I / O ou erros de "comunicação escamosa", apenas erros 401 do Google c2dm.
Uma postagem do serverfault nos levou a pensar sobre o DNS cache na AWS no que se refere à validação SSL do nome do host no certificado oferecido pelo serviço c2dm do Google, mas parece que o urllib2 do python 2.7 que usamos não valida o host por padrão.
Outra pista é que mudamos o endereço IP da primeira instância da web que mostrou o problema, usando o recurso "elástico IP": mesma instância de execução contínua, apenas com um novo IP. Essa instância tornou-se 100% bem sucedida durante 4 dias, mas desde então voltou a ter 401s ocasionais.
O que podemos fazer para esclarecer isso?
Um exemplo de rastreamento de pilha:
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
Exemplos de cabeçalhos HTTP retornados na resposta 401:
'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']
Edite para informações de teste adicionais:
Conseguimos reproduzir esse 401 transitório em uma rede de desenvolvimento. Às vezes funcionava, às vezes, recebia um 401. Como a rede de desenvolvimento é completamente separada da AWS, isso remove todas as variáveis que estávamos considerando sobre a AWS e dá peso à teoria de que o problema está do lado do Google. O Google gentilmente respondeu que eles aumentariam o problema.