Python tornado 打开的文件太多 Ssl

标签 python django ssl tornado

如果我的 tornado 服务器上有很多连接,我会在日志中看到错误

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

并断开我的客户端。 Tornado 在 ewery 连接上打开 ssl 证书文件?

Tornado 应用

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

从django命令启动tornado服务器

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()

为什么他打开很多文件,在我看来需要在启动服务器和所有文件中打开 ssl。 Stackoverflow 会询问更多信息,但最重要的是,所有信息都需要。

最佳答案

您的代码似乎运行多个进程或线程,它们都直接访问 ssl key 文件。 Linux 默认的 ulimit 很快就会变低,然后就会出现这个错误。

您可以通过以下方式检查当前设置:

$ ulimit -a

快速而肮脏的解决方案是增加这个值:

$ ulimit -n <new_value>

-n 选项甚至可以接受 unlimited

注意:您可以永久设置应用程序用户 .bashrc 文件的值。

在这两种情况下,您都需要注销然后登录才能使更改生效。

但是修改这个值有点脏,因为它是给定用户环境的全局值。

更难但更简洁的解决方案是找到一种方法,在您的应用程序加载时将文件内容加载到内存中,并使加载的值/变量可供所有进程访问。

关于Python tornado 打开的文件太多 Ssl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45968587/

相关文章:

python - Python DBM 真的很快吗?

python - celery python对象方法

python - 使用 BeautifulSoup 和 Requests 抓取多个分页链接

django - 我对 app.py 中使用的就绪函数感到困惑

python - 气泡排序开关和旋转挑战

Django 没有名为 path.to 的模块

python - MultipleChoiceField 未在 Django Admin 中显示存储的值

java - 在 Java 运行时加载 CA 根证书

android - 如何为 Android 6.0.1 构建 OpenSSL 1.0.2?

ssl - 带有自签名证书的 Traefik