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

Scala Play+Akka服务报Too many open files崩溃求排查方案

排查与解决思路

一、先确认文件句柄限制是否真的生效

调了ulimit但容器进程未必能拿到,得实打实验证:

  • 进入运行中的容器,执行 ulimit -n 查看当前API进程的文件句柄上限,别只盯着宿主机的配置
  • 检查容器启动参数,比如Docker要加--ulimit nofile=1000000:1000000,K8s得在Pod的securityContext里配置对应文件句柄限制
  • 查看JVM启动参数,有没有设置-XX:MaxFileDescriptorCount,这个参数会直接覆盖系统ulimit值,得确保和你设置的上限匹配

二、定位到底是啥占了文件句柄

光知道句柄不够用没用,得找出元凶:

  • 拿到API进程ID,执行 lsof -p <进程ID> 列出所有打开的句柄,再分类统计:
    • 统计TCP连接数:lsof -p <PID> | grep TCP | wc -l
    • 统计普通文件数:lsof -p <PID> | grep REG | wc -l
  • 重点查TIME_WAIT状态的连接,执行 ss -s 或 netstat -tan | grep TIME_WAIT | wc -l,这类连接大量堆积会吃掉大量句柄

三、检查Akka/Play的连接配置

Play基于Akka HTTP,默认配置可能扛不住生产流量:

  • 打开application.conf,核对这些参数:
    • akka.http.server.idle-timeout:建议设为30-60秒,过长会堆积闲置连接,过短会频繁断开重建
    • akka.http.server.max-connections:设置合理的最大连接数,避免无限制接收新连接导致句柄耗尽
    • akka.http.host-connection-pool.max-open-requests:如果API有对外调用,这个参数控制客户端连接池的最大请求数,防止溢出
  • 检查Akka IO的TCP配置:akka.io.tcp.maximum-open-files,确保和ulimit值一致
  • 排查资源泄漏:比如数据库连接池是否配置超时回收、文件流有没有手动关闭、WebSocket连接是否在客户端离线后正常释放句柄

四、模拟生产流量复现问题

本地复现不了就造流量:

  • 用Gatling或JMeter压测,模拟高并发短连接、长连接混合的场景,尽量贴近生产流量模式
  • 模拟异常场景:比如客户端突然断连、请求超时,看服务端会不会泄漏句柄
  • 压测时实时监控句柄数:watch -n 1 lsof -p <PID> | wc -l,观察句柄数是否持续上涨不回落

五、系统层面的TCP参数优化

就算ulimit够,TCP本身的参数也可能导致连接堆积:

  • 调整TIME_WAIT回收参数:
    • net.ipv4.tcp_tw_reuse = 1:允许重用处于TIME_WAIT状态的连接
    • net.ipv4.tcp_tw_recycle = 1:快速回收TIME_WAIT连接(注意NAT环境下慎用,可能导致连接异常)
    • net.ipv4.tcp_fin_timeout = 30:缩短FIN_WAIT2的超时时间,加快连接释放
  • 调大监听队列:net.core.somaxconn = 65535,避免连接队列溢出导致无法接收新连接

内容的提问来源于stack exchange,提问作者Igor Molchanov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 23:46:01