You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenSSL报Too many open files错误求助:代码还是服务器问题?

解决Python服务中OpenSSL "Too many open files"错误

错误根源分析

这个错误表面是OpenSSL加载证书时无法打开文件,但本质是当前进程打开的文件句柄数量达到了系统或进程的上限,需要从代码写法和服务器配置两方面排查:

1. 代码层面的潜在问题

你的sqlite3操作代码存在句柄泄漏风险,同时要排查SSL相关逻辑:

  • 每次调用__init__、add、get方法都新建数据库连接,虽然显式调用了connection.close(),但如果代码执行中发生异常(比如SQL执行出错),会跳过close()步骤,导致连接未关闭、占用文件句柄。
  • 频繁创建/销毁数据库连接会增加句柄的频繁操作,长期运行下可能积累泄漏。
  • 错误出在OpenSSL环节,要检查服务中是否有重复加载证书文件的逻辑——如果每次发起SSL请求都重新读取证书却不关闭文件句柄,会快速耗尽句柄数。

2. 服务器配置层面的限制

Ubuntu系统默认对进程打开文件数有软限制(通常为1024),24小时运行的服务持续打开文件/连接时,很容易达到这个上限。

解决步骤

代码优化建议

  • 复用数据库连接:改为类初始化时创建一次连接,后续方法复用,服务停止时再关闭,避免频繁创建连接:
class orders :
    def __init__(self):
        self.connection = sqlite3.connect("data.db")
        cursor = self.connection.cursor()
        cursor.execute("CREATE TABLE IF NOT EXISTS Orders (number_orders INTEGER)")
        cursor.execute("SELECT * FROM Orders")  
        entry = cursor.fetchall()   
        print(entry)
        if entry == []:
            cursor.execute("INSERT INTO Orders VALUES (0)") # INTEGER类型无需加引号
        self.connection.commit()

    def add(self):
        cursor = self.connection.cursor()
        cursor.execute("UPDATE Orders SET number_orders=number_orders + 1")     
        self.connection.commit()  

    def get(self):
        cursor = self.connection.cursor()        
        cursor.execute("SELECT number_orders FROM Orders") 
        num=cursor.fetchone()
        return num
    
    def close(self):
        # 服务停止时调用该方法关闭连接
        self.connection.close()
  • 添加异常处理:如果仍需使用短连接,确保异常时也能关闭资源:
def add(self):
    connection = None
    try:
        connection = sqlite3.connect("data.db")
        cursor = connection.cursor()
        cursor.execute("UPDATE Orders SET number_orders=number_orders + 1")     
        connection.commit()
    finally:
        if connection:
            connection.close()
  • 检查SSL逻辑:如果服务中有加载SSL证书的代码,确保读取后关闭文件句柄,或复用加载后的证书对象,不要重复读取文件。

服务器配置调整

  • 临时调整进程句柄限制:启动服务前执行:
ulimit -n 4096

该修改仅对当前shell会话有效,重启后失效。

  • 永久调整限制:编辑/etc/security/limits.conf,添加:
your_username soft nofile 4096
your_username hard nofile 8192

替换your_username为运行服务的用户,重启系统或重新登录生效。

  • 调整系统全局限制:查看/proc/sys/fs/file-max,若数值过小,编辑/etc/sysctl.conf添加:
fs.file-max = 65535

执行sysctl -p使修改生效。

排查验证

  • 用lsof -p <你的服务进程PID>查看当前进程打开的所有文件句柄,确认是否有大量未关闭的sqlite3连接或证书文件。
  • 用ulimit -n查看当前进程的文件句柄软限制值。

内容的提问来源于stack exchange,提问作者muntazir halim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:35:21