关于 liunx 下 IOptionsMonitor 不能即时变化

  今天遇到个奇怪问题,在.net 8中 IOptionsMonitor 选项,修改配置文件后不立即生效,重启服务器后又生效;增加 IOptionsMonitor  OnChange 监听事件后发现在 Windows 情况下能正常监听,在Liunx 下就无法监听;

结解办法和思路:

  在 .NET 8 里 IOptionsMonitor<T> 只有在配置源触发“变更通知”时才会更新(触发 OnChange,并让下一次 CurrentValue 取到新值)。你在 Linux 下改了配置文件但“未生效”,而重启后又生效,通常说明:应用启动时读到了新文件,但运行时没有收到文件变更事件或变更没有被正确绑定/读取。

  检查没有开启 reloadOnChange: true,通常情况下系统默认加载的 appsettings.json 会自动开启;

  如果你自己用 ConfigurationBuilder,需要显式开启:

builder.Configuration
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true, reloadOnChange: true);

  查看Liunx 下  inotify 监听数:

cat /proc/sys/fs/inotify/max_user_instances  (我这默认 128)
cat /proc/sys/fs/inotify/max_user_watches  (我这默认 60696)
cat /proc/sys/fs/inotify/max_queued_events   (我这默认 16384)

  临时调大 监听数:

sudo sysctl -w fs.inotify.max_user_instances=1024   (我只调了这个,重启服务后 Onchange 事件就可以监听到了)
sudo sysctl -w fs.inotify.max_user_watches=524288
sudo sysctl -w fs.inotify.max_queued_events=32768

  永久修改(我这默认就修改一个):

修改
sudo tee /etc/sysctl.d/99-dotnet-inotify.conf >/dev/null <<'EOF' fs.inotify.max_user_instances=1024 EOF

加载:
sudo sysctl --system

检查:
sysctl fs.inotify.max_user_instances
sysctl fs.inotify.max_user_watches
sysctl fs.inotify.max_queued_events

   查看那些进程监听的数量多:

sudo bash -c '
for pid in /proc/[0-9]*; do
  p=${pid#/proc/}
  c=$(ls -l /proc/$p/fd 2>/dev/null | grep -c inotify)
  if [ "$c" -gt 0 ]; then
    cmd=$(tr "\0" " " < /proc/$p/cmdline 2>/dev/null)
    echo "$c $p $cmd"
  fi
done | sort -nr | head -30
'

 总结:

  Linux 上你的进程没能再创建/使用 inotify 实例(fs.inotify.max_user_instances 太小或已被其它进程占满),导致 FileSystemWatcher 失效,从而 IOptionsMonitor.OnChange 不触发;重启后之所以“配置生效”,是因为启动时重新读取了文件,但运行时没法监听变更。

 

posted @ 2026-03-23 09:22  皓月青峰  阅读(1)  评论(0)    收藏  举报