Python 运行多个tornado进程
我读过关于如何运行N个Tornado进程的各种文章和教程,其中N=内核数。我的代码运行正常,在所有16个内核上运行,但我不知怎么搞砸了,我需要重新审视这一点Python 运行多个tornado进程,python,tornado,Python,Tornado,我读过关于如何运行N个Tornado进程的各种文章和教程,其中N=内核数。我的代码运行正常,在所有16个内核上运行,但我不知怎么搞砸了,我需要重新审视这一点 import tornado.ioloop import tornado.web import tornado.httpserver from core import settings from core import coreService import services from tornado.options import def
import tornado.ioloop
import tornado.web
import tornado.httpserver
from core import settings
from core import coreService
import services
from tornado.options import define, options, parse_command_line
define("port", default=settings.SERVER_PORT, help="run on the given port", type=int)
app = tornado.web.Application([
(r'/upload', coreService.Upload)
])
if __name__ == "__main__":
tornado.options.parse_command_line()
server = tornado.httpserver.HTTPServer(app, max_buffer_size=1024*1024*201)
server.bind(options.port)
# autodetect cpu cores and fork one process per core
server.start(0)
try:
print 'running on port %s' % options.port
tornado.ioloop.IOLoop.instance().start()
except KeyboardInterrupt:
tornado.ioloop.IOLoop.instance().stop()
此代码引发以下错误:
File "/opt/tornado/tornado/process.py", line 112, in fork_processes
raise RuntimeError("Cannot run in multiple processes: IOLoop instance "
RuntimeError: Cannot run in multiple processes: IOLoop instance has already been initialized. You cannot call IOLoop.instance() before calling start_processes()
我就是看不出来。多谢各位
:编辑:
正如本所说,我的方法之一就是给我带来麻烦。这是该方法的代码,有些人可能会从中受益:
from tornado import gen
import motor
db = motor.MotorClient().open_sync().proba
class Upload(BaseHandler):
@gen.engine
def post(self):
fs = yield motor.Op(motor.MotorGridFS(db).open)
gridin = yield motor.Op(fs.new_file)
yield motor.Op(gridin.write, 'First part\n')
yield motor.Op(gridin.write, 'Second part')
yield motor.Op(gridin.close)
print gridin._id
self.write(str(gridin._id))
self.finish()
编辑2
我已经找到了问题的最终解决办法。正如本所指出的,上述方法给我带来了麻烦。电机文件中记录了将电机包括在Tornado应用中的正确方法。以下是一个为我工作的例外:
if __name__ == "__main__":
tornado.options.parse_command_line()
try:
server = tornado.httpserver.HTTPServer(app, max_buffer_size=1024*1024*201)
server.bind(8888)
server.start(0) # autodetect cpu cores and fork one process per core
db = motor.MotorClient().open_sync().proba
print 'running on port %s' % options.port
# Delayed initialization of settings
app.settings['db'] = db # from this point on db is available as self.settings['db']
tornado.ioloop.IOLoop.instance().start()
except KeyboardInterrupt:
tornado.ioloop.IOLoop.instance().stop()
如果我将“核心”和“服务”导入注释掉,它将按预期工作。这些模块中的某个模块必须初始化singleton事件循环(可能是间接的,例如通过创建全局AsyncHTTPClient实例)。此警告可防止在父进程中创建的这些对象在子进程中不起作用。您必须找到创建这些对象的位置(遗憾的是,没有很好的工具),并将它们移动到fork之后,以便在子进程中创建它们。在tornado.web.Application的调试模式下会出现此异常
application = tornado.web.Application([
(r"/", hello),
],
debug=False)
将debug设置为False可修复此问题
您可以启动多个进程来侦听每个端口:
server = tornado.httpserver.HTTPServer(application)
server.bind(1234) # port
server.start(4)
tornado.ioloop.IOLoop.instance().start()
即使设置
debug=False
和autoreload=False
我的嫌疑犯将注意力集中在MotorClient
上,即在TornadApp上创建实例
注释motor\u client=…
line解决了我的问题
class MainApp(tornado.web.Application):
def __init__(self):
handlers = [
(r"/", views.HomeHandler),
(r".*", views.NotFoundHandler),
]
motor_client = motor.motor_tornado.MotorClient('mongodb://localhost:27017')
不幸的是,使用MotorClient
迫使我放弃使用多进程运行Tornado。对您选择的版本控制系统中的工作版本使用diff功能,应该可以告诉您如果出现故障会发生什么变化。这解决了我的问题。非常不直观。谢谢。谢谢,这可能是最常见的问题。谢谢,这个答案对我有帮助。根据代码中的注释,autoreload实际上是罪魁祸首,当debug=True时,autoreload默认为True。如果在应用程序创建中显式设置autoreload=False,则可以保持debug=True。@wojtow。我明确定义了autoreload=True
,这就是问题的原因。请您也看看这个: