在多进程模式下使用aiomysql运行tornado

时间:2017-03-13 15:37:17

标签: python-3.x tornado python-asyncio

我一直在尝试使用以下代码在多进程模式下使用aiomysql运行龙卷风

@asyncio.coroutine
def get_mysql_connection(loop):
    return (yield from aiomysql.create_pool(host=host,port=3306,user=user, password=pass, db=db, loop=loop))


if __name__ == "__main__":
    tornado.platform.asyncio.AsyncIOMainLoop().install()
    ioloop = asyncio.get_event_loop()
    mysql = ioloop.run_until_complete(get_mysql_connection(ioloop))
    options.parse_config_file("app.conf")
    app = make_app(mysql)
    print('listening on %s:%s...' %(options.host, options.port))
    server = tornado.httpserver.HTTPServer(app)
    server.listen(options.port)
    server.start(0) #this is my problem
    ioloop.run_forever()

但我一直收到以下错误

RuntimeError: Cannot run in multiple processes: IOLoop instance has already been initialized. You cannot call IOLoop.instance() before calling start_processes()

ioloop.start(0)行外,一切正常,是否可以使两个库aiomysqltornado在多进程模式下正常工作?如果没有我的其他选择

龙卷风版本4.4.2

python版本3.6.0

aiomysql版本0.0.9

1 个答案:

答案 0 :(得分:1)

就像消息所说的那样,只有在初始化IOLoop之前执行它才能分叉工作进程。使用AsyncIOMainLoop会有一些细微之处,因为您希望尽早安装它。解决方案是按照以下顺序启动程序:

tornado.options.parse_config_file(...)
socks = tornado.netutil.bind_sockets(options.port, options.host)
tornado.process.fork_processes(0)
tornado.asyncio.AsyncIOMainLoop().install()
# Initialize the rest of your app, create the HTTPServer, 
# and instead of listen() or start(), do
server.add_sockets(socks)
  

我的其他选择是什么

在我看来,最好使用像supervisord这样的外部流程管理器,而不是在应用程序中分支多个进程。这避免了大多数这些初始化顺序陷阱。