/dev/shm 写满导致 nginx shared memory 分配失败的 shm 限制方案

发布时间 - 2026-01-30 00:00:00    点击率:
/dev/shm 写满导致 nginx shared memory 分配失败,因其依赖 shm_open() 在 tmpfs 类型的 /dev/shm 中创建内存段,空间耗尽时返回 ENOSPC;需通过 fstab 持久化扩容或优化 nginx zone 配置来解决。

为什么 /dev/shm 写满会让 nginx 的 shared memory 分配失败

nginx 的 limit_req_zonelimit_conn_zonessl_session_cache 等功能依赖 shm(POSIX shared memory),底层通过 shm_open()/dev/shm 下创建匿名内存段。这个目录本质是 tmpfs,挂载在内存中,默认大小通常为 64MB(取决于内核版本和发行版)。一旦其他进程(如数据库临时表、Python 的 multiprocessing、自定义 shm 段)持续写入且未清理,/dev/shm 耗尽,nginx reload 或启动时调用 shm_open() 就会返回 ENOSPC,日志里出现类似:

nginx: [emerg] unable to create shared memory zone "xxx": cannot open shared memory object "/xxx" (28: No space left on device)

这不是磁盘空间问题,而是 tmpfs 内存配额用完了。

调整 /dev/shm 大小的两种可靠方式

不能只靠 mount -o remount,size=... 临时生效,必须确保重启后持久、且不被 systemd-tmpfiles 覆盖。

  • 推荐方案:修改 /etc/fstab,添加或修正这一行(例如设为 1G):
    tmpfs /dev/shm tmpfs defaults,size=1G 0 0
  • 替代方案(仅限 systemd 系统):创建 /etc/tmpfiles.d/shm.conf,内容为:
    u root root 1777 /dev/shm 0 0
    然后执行 systemd-tmpfiles --create;但注意:该方式不支持直接指定 size,需配合 MountFlags=shared 和额外 mount unit,不如 fstab 稳定
  • 验证是否生效:findmnt -t tmpfs /dev/shm 应显示正确 size;df -h /dev/shm 需反映新值

nginx 自身 shm 使用量是否可优化

增大 /dev/shm 是兜底手段,但更应检查 nginx 配置是否过度申请共享内存——尤其当 zone 名称重复、reload 频繁、或使用了未清理的第三方模块时。

  • limit_req_zonelimit_conn_zonezone=name:sizesize 值要合理:1MB 通常可容纳约 16k key(取决于 key 长度和 hash 表负载因子),不必默认写 100M
  • 避免在 http 块外(如 stream 或多个 server 里)重复定义同名 zone,否则每次 reload 都新建 shm 段,旧段残留(直到所有 worker 退出)
  • 检查是否有模块(如 ngx_http_geoip2_module 或自研模块)在 init 阶段调用 shm_alloc 但未正确注册 cleanup 回调
  • 临时诊断:ls -l /dev/shm/ | grep nginx 可看到残留的 /nginx_* 段;正常运行时一般只有 1–2 个,若数量持续增长,说明有泄漏

监控和自动清理的实用建议

生产环境不能只靠人工发现 /dev/shm 满了才处理,得有防御机制。

  • 加入基础监控项:df -P /dev/shm | awk 'NR==2 {print $5}' | sed 's/%$//',告警阈值建议设为 80%
  • 不建议 cron 定期 rm -f /dev/shm/nginx_*:可能误删正在使用的段,导致 nginx worker crash(SIGBUS)
  • 安全清理方式:先确认哪些 shm 段无关联进程:lsof +D /dev/shm 2>/dev/null | grep -v "nginx:";再针对无输出的文件执行 rm
  • 更稳妥的做法是限制上游使用方:比如 PostgreSQL 的 temp_buffers、Python 的 multiprocessing.shared_memory 显式指定 name 并 ensure close/unlink,避免无名段堆积

正麻烦的不是容量不够,而是不同组件对 /dev/shm 的生命周期管理策略不一致——nginx 依赖进程退出自动释放,而有些应用会显式 unlink 却忘了 close,有些则完全不 unlink。这类混合使用场景下,光调大 size 只是延缓问题爆发时间。


# python  # nginx  # ssl  # session  # stream  # 为什么  # red  # print  # NULL  #   # postgresql  # 数据库  # http  # 设为  # 写满  # 只靠  # 就会  # 多个  # 两种  # 这类  # 这不是  # 会让  # 自定义 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?  Laravel怎么使用Intervention Image库处理图片上传和缩放  Win11怎么开启自动HDR画质_Windows11显示设置HDR选项  WEB开发之注册页面验证码倒计时代码的实现  Laravel怎么配置S3云存储驱动_Laravel集成阿里云OSS或AWS S3存储桶【教程】  潮流网站制作头像软件下载,适合母子的网名有哪些?  Laravel Seeder怎么填充数据_Laravel数据库填充器的使用方法与技巧  Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】  Laravel怎么实现微信登录_Laravel Socialite第三方登录集成  Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门  中国移动官方网站首页入口 中国移动官网网页登录  绝密ChatGPT指令:手把手教你生成HR无法拒绝的求职信  如何用PHP工具快速搭建高效网站?  深圳网站制作的公司有哪些,dido官方网站?  Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】  canvas 画布在主流浏览器中的尺寸限制详细介绍  如何在云指建站中生成FTP站点?  Laravel怎么上传文件_Laravel图片上传及存储配置  如何在宝塔面板中修改默认建站目录?  Laravel怎么调用外部API_Laravel Http Client客户端使用  为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】  MySQL查询结果复制到新表的方法(更新、插入)  北京网站制作的公司有哪些,北京白云观官方网站?  java中使用zxing批量生成二维码立牌  LinuxShell函数封装方法_脚本复用设计思路【教程】  简历在线制作网站免费版,如何创建个人简历?  Laravel Seeder填充数据教程_Laravel模型工厂Factory使用  手机网站制作与建设方案,手机网站如何建设?  通义万相免费版怎么用_通义万相免费版使用方法详细指南【教程】  Laravel如何生成API文档?(Swagger/OpenAPI教程)  东莞专业网站制作公司有哪些,东莞招聘网站哪个好?  胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?  Laravel怎么进行浏览器测试_Laravel Dusk自动化浏览器测试入门  Laravel辅助函数有哪些_Laravel Helpers常用助手函数大全  原生JS获取元素集合的子元素宽度实例  php静态变量怎么调试_php静态变量作用域调试技巧【解答】  如何安全更换建站之星模板并保留数据?  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南  Laravel怎么生成URL_Laravel路由命名与URL生成函数详解  网站制作软件有哪些,制图软件有哪些?  香港服务器租用每月最低只需15元?  Laravel事件监听器怎么写_Laravel Event和Listener使用教程  Laravel如何实现API版本控制_Laravel版本化API设计方案  如何在香港免费服务器上快速搭建网站?  北京的网站制作公司有哪些,哪个视频网站最好?  成都品牌网站制作公司,成都营业执照年报网上怎么办理?  简单实现Android文件上传  谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程  Windows10电脑怎么查看硬盘通电时间_Win10使用工具检测磁盘健康