简体   繁体   English

Python龙卷风打开文件太多Ssl

[英]Python tornado Too many open files Ssl

If i have many connection on my tornado server, i se error on log 如果我的龙卷风服务器上有很多连接,我在日志中会出错

Exception in callback (<socket._socketobject object at 0x7f0b9053e3d0>, <function null_wrapper at 0x7f0b9054c140>)
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/tornado/ioloop.py", line 888, in start
    handler_func(fd_obj, events)
  File "/usr/local/lib/python2.7/dist-packages/tornado/stack_context.py", line 277, in null_wrapper
    return fn(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/tornado/netutil.py", line 276, in accept_handler
    callback(connection, address)
  File "/usr/local/lib/python2.7/dist-packages/tornado/tcpserver.py", line 264, in _handle_connection
  File "/usr/local/lib/python2.7/dist-packages/tornado/netutil.py", line 517, in ssl_wrap_socket
    context = ssl_options_to_context(ssl_options)
  File "/usr/local/lib/python2.7/dist-packages/tornado/netutil.py", line 494, in ssl_options_to_context
    context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None))
IOError: [Errno 24] Too many open files

and disconnect my client. 并断开我的客户。 Tornado open ssl certificate file on ewery connect? 在Every Connect上龙卷风打开SSL证书文件?

Tornado app 龙卷风应用

class VastWebSocket(tornado.websocket.WebSocketHandler):
connections = set()
current_connect = 0
current_user = 0
status_play_vast = False

def open(self):
    c = Connection()
    c.connection = self

VastWebSocket.connections.add(c)
self.current_connect = c

def on_message(self, msg):

data = json.loads(msg)

app_log.info("on message = " + msg)

if not 'status' in data:
  return

if data["status"] == "start_vast":
  VastWebSocket.status_play_vast = True

if data["status"] == "end_vast":
  VastWebSocket.status_play_vast = False

app_log.info("status_play_vast = " + str(VastWebSocket.status_play_vast))

if data["status"] == "get_status_vast":
  self.current_connect.connection.write_message({"status": VastWebSocket.status_play_vast})
  return

for conn in self.connections:
        conn.connection.write_message(msg)


def on_close(self):
if self.current_connect <> 0:
  VastWebSocket.connections.remove(self.current_connect)


def check_origin(self, origin):
return True

Start tornado server from django command 从Django命令启动龙卷风服务器

class Command(BaseCommand):
    help = 'Starts the Tornado application for message handling.'

def add_arguments(self, parser):
    parser.add_argument('port_number', nargs='+', type=int)

def sig_handler(self, sig, frame):
    """Catch signal and init callback"""
    tornado.ioloop.IOLoop.instance().add_callback(self.shutdown)

def shutdown(self):
    """Stop server and add callback to stop i/o loop"""
    self.http_server.stop()

    io_loop = tornado.ioloop.IOLoop.instance()
    io_loop.add_timeout(time.time() + 2, io_loop.stop)

def handle(self, *args, **options):
    if "port_number" in options:
        try:
            port = int(options["port_number"][0])
        except ValueError:
            raise CommandError('Invalid port number specified')
    else:
        port = 8030

    ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
    ssl_ctx.load_cert_chain(os.path.join("/www/cert/", "rumma.crt"),
            os.path.join("/www/cert/", "rumma.key"))

    self.http_server = tornado.httpserver.HTTPServer(application, ssl_options = ssl_ctx)


    self.http_server.bind(port, address="0.0.0.0")
    self.http_server.start(1)
    # Init signals handler
    signal.signal(signal.SIGTERM, self.sig_handler)

    # This will also catch KeyboardInterrupt exception
    signal.signal(signal.SIGINT, self.sig_handler)

    tornado.ioloop.IOLoop.instance().start()

Why his open many file, in my mind need open ssl in start server and all. 为什么他要打开许多文件,在我看来需要在启动服务器和所有服务器中打开ssl。 Stackoverflow asks more info, but in top, all info all need. Stackoverflow询问更多信息,但最重要的是,所有信息都需要。

Your code seems to run multiple process or thread that all accessing to the ssl keyfile directly. 您的代码似乎运行多个都直接访问ssl密钥文件的进程或线程。 Linux default ulimit is quick low and this error then occurs. Linux默认ulimit很快过低,然后发生此错误。

You can check the current setting with: 您可以使用以下方法检查当前设置:

$ ulimit -a

The quick and dirty solution is to increase this value: 快速而肮脏的解决方案是增加此值:

$ ulimit -n <new_value>

Even unlimited is accepted with the -n option. -n选项甚至接受unlimited

Note: You can permanently set the value the app user .bashrc file. 注意:您可以永久设置应用程序用户.bashrc文件的值。

In both case you'll need to log out then log in for the change to take effect. 在这两种情况下,您都需要注销然后登录才能使更改生效。

But modifying this value is a bit dirty because it's a global value for a given user environment. 但是修改此值有点脏,因为它是给定用户环境的全局值。

The harder but cleaner solution is to find a way to load the content of the file in memory when your app load and make the loaded value/variable accessible for all processes. 较难但较干净的解决方案是找到一种方法,以在应用程序加载时将文件内容加载到内存中,并使加载的值/变量可用于所有进程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM