我使用 gunicorn 17.5 和worker_class="gevent", workers=3
,我从gunicorn -c config.py my:app
. 我刚刚在我的日志中注意到以下错误
2014-04-01 04:48:49 [4297] [ERROR] Error handling request
Traceback (most recent call last):
File "/usr/lib/python2.6/site-packages/gunicorn/workers/async.py", line 45, in handle
self.handle_request(listener, req, client, addr)
File "/usr/lib/python2.6/site-packages/gunicorn/workers/ggevent.py", line 119, in handle_request
super(GeventWorker, self).handle_request(*args)
File "/usr/lib/python2.6/site-packages/gunicorn/workers/async.py", line 93, in handle_request
respiter = self.wsgi(environ, resp.start_response)
File "/usr/lib/python2.6/site-packages/beaker/middleware.py", line 155, in __call__
return self.wrap_app(environ, session_start_response)
[...]
File "/usr/lib/python2.6/site-packages/mysql/connector/connection.py", line 1083, in cursor
if not self.is_connected():
File "/usr/lib/python2.6/site-packages/mysql/connector/connection.py", line 696, in is_connected
self.cmd_ping()
File "/usr/lib/python2.6/site-packages/mysql/connector/connection.py", line 665, in cmd_ping
return self._handle_ok(self._send_cmd(ServerCmd.PING))
File "/usr/lib/python2.6/site-packages/mysql/connector/connection.py", line 378, in _send_cmd
return self._socket.recv()
File "/usr/lib/python2.6/site-packages/mysql/connector/network.py", line 170, in recv_plain
packet = self.sock.recv(1)
File "/usr/lib64/python2.6/site-packages/gevent/socket.py", line 432, in recv
wait_read(sock.fileno(), timeout=self.timeout, event=self._read_event)
File "/usr/lib64/python2.6/site-packages/gevent/socket.py", line 165, in wait_read
assert event.arg is None, 'This event is already used by another greenlet: %r' % (event.arg, )
AssertionError: This event is already used by another greenlet: (<Greenlet at 0x37ac190: <functools.partial object at 0x2578788>(<socket at 0x37ab9d0 fileno=14 sock=10.174.17.169:, ('173.228.6.207', 18614))>, timeout('timed out',))
一点点搜索似乎表明我可能正在使用一些模块,这些模块在导入之前没有进行猴子修补或与 greenlet 不兼容。然而 mysql 连接器是纯 python ,所以这似乎意味着它是兼容的。并且worker_class=gevent
似乎monkey.patch_all()
在初始化时调用。可以肯定的是,我import gevent.monkey; gevent.monkey.patch_all()
在我的应用程序的第一行添加了,但它没有帮助。我注意到的最后一件事:当我 ctrl-c 我的应用程序时,我得到了这个
Exception KeyError: KeyError(36957072,) in <module 'threading' from '/usr/lib64/python2.6/threading.pyc'> ignored
我在网上读到这表明在导入线程后完成了猴子补丁。考虑到我提到的上下文,知道怎么会发生这种情况吗?
如果有帮助:我的应用程序在启动时会打开一堆 mysql 连接,但我不保证它们将被专门使用——即我没有具有获取/释放语义的连接池,它们只是由传入的客户端请求随机使用。拥有某种连接池会有所帮助吗?如果是,如何确保这与 gevent/greenlets 很好地配合使用?