Nginx 不通过 kqueue 监控文件变更,kqueue 仅作为 BSD/macOS 系统上的网络 I/O 多路复用机制;配置更新必须手动执行 nginx -t 验证后 nginx -s reload 才生效。

Nginx 本身并不通过 kqueue 实现文件变更的自动监控,它也不具备原生的、持续监听配置文件或证书等文件变化并自动重载的功能。
kqueue 是什么,和 Nginx 有什么关系?
kqueue 是 FreeBSD、macOS 等 BSD 衍生系统提供的高效事件通知机制,类似 Linux 的 inotify。Nginx 在这些系统上编译时,可启用 kqueue 作为其 网络 I/O 多路复用机制(即处理客户端连接、读写事件),但它仅用于网络事件,不用于监听文件系统变更。
Nginx 的源码中,kqueue 相关逻辑集中在 src/event/modules/ngx_kqueue_module.c,作用是替代 select/poll,提升高并发下的网络性能——与文件监控无关。
Nginx 不监听文件变更,那配置更新怎么生效?
Nginx 设计为“静态配置 + 显式重载”,所有变更(如修改 nginx.conf、更新 SSL 证书、调整 upstream)都需要手动触发重载,而非后台自动感知:
-
nginx -s reload:向主进程发送SIGHUP,主进程校验配置、启动新 worker,平滑切换 -
nginx -t:必须先验证语法和路径有效性,避免 reload 失败导致服务中断 - 证书或文件内容变更后,即使路径没变,Nginx 也不会重新读取——它只在 reload 时按配置路径打开并读取一次
如果真想实现“文件变更自动 reload”,得靠外部工具
可在 BSD/macOS 上结合 kqueue(或 Linux 的 inotifywait)+ shell 脚本实现自动化,例如使用 kqueue-感知工具 entr:
# 监听 nginx 配置目录下所有 .conf 文件变化 find /usr/local/etc/nginx -name "*.conf" | entr -d nginx -t && nginx -s reload
或者用更健壮的方式(带错误防护):
- 用
launchd(macOS)或rc.d(FreeBSD)管理守护脚本 - 脚本中调用
kevent()或封装好的watchman/fswatch监听文件变化 - 检测到变更后,先
nginx -t,成功再nginx -s reload,失败则记录日志
注意几个常见误区
• kqueue 支持文件监控(EVFILT_VNODE),但 Nginx 源码里 完全没有使用它来 watch 配置文件
• 修改 nginx.conf 后不 reload,旧配置一直生效;worker 进程不会重新读取磁盘文件
• 第三方模块(如 nginx-module-vts)或 OpenResty 的 resty.file 也不改变这一行为
• Docker 环境中挂载配置文件时,仍需外部信号(如 docker exec nginx nginx -s reload)或 sidecar 容器驱动










