问题描述
我正在使用Gevent PyWsgi和MysqL Connector作为数据库驱动程序来开发Flask服务器。在monkey_patch使其并发服务多个请求之后,我发现有时我的服务器挂起了两个或多个并发请求,并且我必须重新启动服务器才能使其工作。 详细信息:
- 我设置了MysqL连接池(pool_size = 10),并在应用程序上共享了该单个池实例。
class PoolManager:
def __init__(self,*args,**kwargs):
self.args = args
self.kwargs = kwargs
self._init()
def _init(self):
self._pool = MysqLConnectionPool(*self.args,**self.kwargs)
def get_connection(self):
#logging greenlet id
print("Start get connection from pool....")
print("GID {}".format(id(gevent.getcurrent())))
new_cnx = self._pool.get_connection()
print(" -------CONN_ID: {}".format(new_cnx.__getattr__("connection_id")))
return new_cnx
- 开始运行时,一切似乎都还不错,我看到该池初始化了与MysqL的10个连接,并且工作正常。每个即将到来的请求已同时得到处理。
- 一段时间后,我又发出了2个请求。.stdout被卡在上面的日志行中:
Start get connection from pool....
GID 123xxxxx
Start get connection from pool....
GID 321xxxxx
然后什么也没有发生。 MysqL连接(通过show processlist
)正在全部休眠,我的服务器已挂起。
所以,我的问题是:
- 我在这里有比赛条件吗?哪里有问题? Gevent Pywsgi还是MysqL Connector?
- 这里哪种方法正确? MysqLConnectionPool不能在线程上重用,我应该为每个greenlet初始化每个连接吗?
解决方法
对于gevent,您可能需要特定的mysql模块。 UltraMysql位于: https://github.com/esnme/ultramysql
您应该在此处查看此示例。这在我所有的生产环境中都很好。