Python 使用gevent访问外部http服务时出现间歇性问题

Python 使用gevent访问外部http服务时出现间歇性问题,python,exception,gevent,gunicorn,python-requests,Python,Exception,Gevent,Gunicorn,Python Requests,首先,版本: gevent-v0.13.7 gunicorn-v0.14.2 请求-0.11.2 我们最近升级了运行在gunicorn后面的服务器,以使用gevent异步工作程序,而不仅仅是普通的同步工作程序。一切都很好,但我们现在在尝试通过http访问第三方服务时遇到了一个问题,我不知道如何跟踪可能出现的问题 简短的堆栈跟踪如下所示: File "/home/deploy/.virtualenvs/bapp/lib/python2.7/site-packages/requests/sess

首先,版本:

  • gevent-v0.13.7
  • gunicorn-v0.14.2
  • 请求-0.11.2
我们最近升级了运行在gunicorn后面的服务器,以使用gevent异步工作程序,而不仅仅是普通的同步工作程序。一切都很好,但我们现在在尝试通过http访问第三方服务时遇到了一个问题,我不知道如何跟踪可能出现的问题

简短的堆栈跟踪如下所示:

File "/home/deploy/.virtualenvs/bapp/lib/python2.7/site-packages/requests/sessions.py", line 295, in post
  return self.request('post', url, data=data, **kwargs)
File "/home/deploy/.virtualenvs/bapp/lib/python2.7/site-packages/requests/sessions.py", line 252, in request
  r.send(prefetch=prefetch)
File "/home/deploy/.virtualenvs/bapp/lib/python2.7/site-packages/requests/models.py", line 625, in send
  raise ConnectionError(sockerr)
ConnectionError: [Errno 66] unknown
另一个不同的堆栈跟踪,但我们认为是同一个问题:

File "/home/deploy/.virtualenvs/bapp/lib/python2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 94, in connect
  sock = socket.create_connection((self.host, self.port), self.timeout)
File "/home/deploy/.virtualenvs/bapp/lib/python2.7/site-packages/gevent/socket.py", line 637, in create_connection
  for res in getaddrinfo(host, port, 0, SOCK_STREAM):
File "/home/deploy/.virtualenvs/bapp/lib/python2.7/site-packages/gevent/socket.py", line 769, in getaddrinfo
  raise
DNSError: [Errno 66] unknown
起初,我认为它可能与一个
libevent dns
有关。我检查了我们的
/etc/resolv.conf
,发现只有一个dns解析服务:

[me@host:~]$ cat /etc/resolv.conf
; generated by /sbin/dhclient-script
nameserver 10.3.0.2
我查了一下ERRNO66是什么:,“/**发生了未知错误*/”。我没有太多的运气发现这有帮助..听起来好像它无法与dns服务器对话

我认为它可能与
python请求
有关,因为
python请求
依赖于
urlib3
,它是根据
httplib
实现的;但是,
gevent
的作者在今年早些时候删除了commit中的
httplib
补丁,但没有说明原因

有没有人对如何调试这个问题有任何想法,或者可能会对这里发生的事情有所了解

提前谢谢

更新-太平洋时间下午12:50 在freenode上进行了一些对话之后,#gevent和#gunicorn频道似乎透露了更多的见解:

#格温特
  • gevent v0.13.7仍然支持带有
    httplib=True的
    patch\u all
  • 我问“修补它是否有意义?”,回答是否定的
  • 建议使用gevent 1.0(即使是beta版)
  • 引用@schmir:

    修补程序httplib使用libevent http客户端库。我不信任libevent。如果您使用它,我的建议是将其关闭

#古尼科恩
  • 您的平台是什么?我已经看到这个问题出现在windows框中,它尝试ipv6,但却失败了。。(我在CentOS 5上)
  • 我在mac上看到过类似的情况,看起来gevent beta修复了它
听起来一般的建议是放弃gevent v0.13.7并升级到gevent 1.0b

我会跟进,如果这解决了这个问题。同时,任何能提出建议的人,我都非常感激

更新#生产2-4天,PDT下午1:15
看来升级到
gevent
解决了这个问题——如果没有其他人插话,我会添加我的答案并接受它,但必须在一周的生产过程中没有发生任何事件之后。

升级到gevent 1.0b已经消除了这个问题。

上次测试gevent 1.0(libev)我遇到了这样一个问题:解析300个主机名的示例运行大约2秒,而0.13(libevent)版本运行大约0.1秒。0.13使用libevent解析机制和缓存,而1.0使用c-ares。至于你的问题:如果这是可复制的-你可以尝试Straging。升级到gevent 1.0b(libev)似乎已经消除了DNSError的问题。这个问题是不可复制的,但实际上是断断续续的,对我们的业务造成了很大的破坏。我将密切关注这些性能问题,同时,我建议您通知gevent的团队,以便他们了解您未来的问题。