【问题标题】:Intermittent issues while accessing external http services using gevent使用 gevent 访问外部 http 服务时出现间歇性问题
【发布时间】:2012-09-13 18:40:17
【问题描述】:

首先,版本:

  • gevent - v0.13.7
  • gunicorn - v0.14.2
  • 请求 - 0.11.2

我们最近升级了在 gunicorn 后面运行的服务器,以使用 gevent 异步工作程序,而不仅仅是普通的同步工作程序。一切正常,但我们现在在尝试通过 http 访问 3rd 方服务时遇到了问题,我只是不知道如何追踪可能是什么问题。

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

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 相关,来自google groups issue。我查了我们的/etc/resolv.conf,只有一个dns解析服务:

[me@host:~]$ cat /etc/resolv.conf
; generated by /sbin/dhclient-script
nameserver 10.3.0.2

我查看了 ERRNO66 是什么:https://github.com/libevent/libevent/blob/master/include/event2/dns.h#L162,"/** 发生未知错误 */"。我没有太多运气找到有用的东西..听起来它无法与 dns 服务器通信?

我认为它可能与python-requests 相关,参见how enable requests async mode?,因为python-requests 依赖于urllib3,它是根据httplib 实现的;但是,事实证明gevent 的作者在今年早些时候的this 提交中删除了httplib 补丁,而没有任何关于原因的cmets。

是否有人对如何调试此问题有任何想法,或者可能对这里发生的事情有所了解?

提前致谢!

更新 - 太平洋夏令时间下午 12:50

在 freenode 上进行了一些对话后,#gevent 和 #gunicorn 频道似乎有了更多的见解:

#gevent

  • gevent v0.13.7 仍然支持patch_allhttplib=True
  • 我问“修补它是否有意义?”,回答是否定的。
  • 建议使用 gevent 1.0(即使它是测试版)。
  • 来自@schmir 的引用:

    “patch httplib 使用 libevent http 客户端库。我不信任 libevent。如果你使用它,我的建议是关闭它”

#gunicorn

  • <Damianz>你的平台是什么?我已经看到这个问题出现在它尝试 ipv6 并且只是失败的 Windows 盒子上。(我在 CentOS 5 上)
  • <dmishe>我在mac上看到过类似的,看起来gevent beta修复了它

听起来一般建议是放弃 gevent v0.13.7 并升级到 gevent 1.0b。

如果解决了这个问题,我会跟进。同时,任何可以提出建议的人,我将不胜感激。

更新 #2 - 生产 4 天,太平洋夏令时间下午 1:15

看来升级到gevent 已经解决了这个问题——如果没有其他人介入,我会添加我的答案并接受它,但只有在生产中没有发生任何事件一周之后。

【问题讨论】:

  • 我上次测试 gevent 1.0 (libev) 时遇到问题,解析 300 个主机名的示例运行大约 2 秒,而 0.13 (libevent) 版本运行 0.1 秒左右。 0.13 使用 libevent 解析机制和缓存,而 1.0 使用 c-ares。至于你的问题:如果这是可重现的 - 你可以尝试追踪。
  • 升级到 gevent 1.0b(libev) 似乎消除了 DNSError 的问题。这个问题是不可重现的,但实际上是断断续续的,对我们的业务非常具有破坏性。我会密切注意这些性能问题,同时,我建议您通知 gevent 的团队,以便他们了解您的问题。

标签: python exception gevent gunicorn python-requests


【解决方案1】:

升级到 gevent 1.0b 已经解决了这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 2019-04-16
    • 1970-01-01
    相关资源
    最近更新 更多