gevent.monkey.patch_all()之后的max_user_connections

时间:2014-05-26 12:38:09

标签: python mysql monkeypatching gevent-socketio greenlets

我在基于django的网络应用上使用gevent-socketio v0.13.8进行聊天应用。我的数据库是MySql,其max_user_connection = 1500。我的套接字服务器是用python守护进程守护进程的。我正在使用没有猴子补丁的套接字服务器并且运行良好,除非在greenlet上出现错误,所有系统都因SystemExit而失败,并且不再建立连接。解决方案是重新启动所有服务器。

但是我不想每次都重启服务器。最后我想出了猴子修补的想法。我不知道它是否与我的问题有关但我希望我的套接字服务器能够运行,即使未处理的异常导致greenlet上的SystemExit。

然后我在我的服务器启动函数中使用了gevent.monkey.patch_all()。现在这是我的主要问题:在3-4个连接之后,MySql导致以下错误:

User xxx already has more than 'max_user_connections' active connections

mysql server中的max_user_connection变量设置为1500。我认为有些东西会在greenlets中创建与数据库的新连接。

顺便说一下,当我使用时,不会出现max_user_connection错误:

monkey.patch_all(socket=True, dns=True, time=True, select=True, thread=True, os=True, ssl=True, httplib=True, aggressive=True)

而不是:

monkey.patch_all()

有没有办法使用猴子修补而不会出现此错误?如果我忘记提供有关问题定义的任何信息,请告诉我,我会立即更新

这是我的守护程序服务器代码:

class App():

    def __init__(self):
        self.stdin_path = 'xxx.txt'
        self.stdout_path = 'xxx.txt'
        self.stderr_path = 'xxx.txt'
        self.pidfile_path =  'xxx.pid'
        self.pidfile_timeout = 5

    def run(self):
        from socketio.server import SocketIOServer
        from gevent import monkey
        monkey.patch_all()
        while True:
            try:
                bind = ("xx.xx.xx.xx", xxxx)
                handler = get_handler()
                server = SocketIOServer(bind, handler, resource="socket.io",policy_server=False)
                server.serve_forever()
            except:
                server.kill()
app = App()
logger = logging.getLogger("DaemonLog")
logger.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler = logging.FileHandler("xxx.log")
handler.setFormatter(formatter)
logger.addHandler(handler)

daemon_runner = runner.DaemonRunner(app)
daemon_runner.daemon_context.files_preserve=[handler.stream]
daemon_runner.do_action()

1 个答案:

答案 0 :(得分:0)

我在https://github.com/abourget/gevent-socketio/issues/174

找到了解决问题的方法

它实际上与greenlets的非封闭数据库连接有关。 在我的命名空间类中添加类似的exception_handler_decorator后,我没有看到max_user_connection错误

from django.db import close_old_connections  # Django 1.6
class MyNamespace(BaseNamespace):
    ...
    def exception_handler_decorator(self, fun):
        def wrap(*args, **kwargs):
            try:
                return fun(*args, **kwargs)
            finally:
                close_old_connections()
        return wrap
    ...