设计应用程序以支持配置更改,而无需重新启动

Designing application to support config changes without restart

本文关键字:重新启动 应用程序 支持 配置      更新时间:2023-10-16
有哪些

方法可以设计应用程序,以便在不需要重新启动应用程序的情况下更改配置?

一种方法是只有一个包含配置的平面文件,然后应用程序在需要特定值时从配置中读取,并且从不在内存中存储任何配置值。

另一种选择是允许应用程序加载配置文件一次并将值存储在内存中,但随后定期重新加载配置文件,以防发生更改。

碰巧的是,我最近更新了一个免费软件包来做到这一点。我采取的方法略有不同。

1) 我的应用程序加载其配置,解析它,并将其存储在内存中。每次应用程序需要某些配置设置的值时,我都不会读取配置设置。

2)但是,除了配置设置外,我还存储配置文件本身的时间戳。

3) 当应用程序唤醒以响应事件并且它有事情要做时,它会检查配置文件的时间戳。如果未更改,则不采取进一步操作。stat(2) 系统调用是轻量级的, 便宜的, 而且快速, 并且增加的开销很小。

4) 如果stat(2)告诉我配置文件的时间戳已更改,应用程序将再次读取配置文件。

作为其格式的一部分,配置文件包括一个明确的"配置结束"标记。如果我的应用程序看不到它,这意味着我应该出去玩下一次彩票,因为我设法遇到了一个极其罕见的竞争条件,在这种情况下,当我的应用程序以某种方式最终读取一个新的配置文件时,该文件正在被我用来同时编辑配置文件的编辑器保存!

如果代码看不到"配置结束"标记,则在应用程序下次唤醒并检查配置文件的时间戳之前,不会执行进一步的操作。

5) 读取并解析新配置文件后,我验证新的配置设置。此处进行一些内部健全性检查。如果健全性检查失败,则在向系统日志报告错误后不会采取进一步的操作。

6) 只有在健全性检查通过后,以前存储的配置设置和值才会被从新配置文件读取的更新值以及新配置文件的较新时间戳替换。直到下次我们再见面。

附言保存的配置设置受互斥锁保护。当应用程序需要检查特定配置设置的值时,它会持有互斥锁。步骤 6 还会获取足够长的互斥锁,以便将当前配置设置替换为新验证的更新配置设置。

为避免轮询,请考虑使用来自操作系统的通知来确定配置文件何时被修改。大多数操作系统都提供可执行此操作的 API:

  • Linux: inotify
  • Windows: ReadDirectoryChangesW
  • Mac: FSEvents
有许多

跨平台包装器(例如,这里和这里)可以简化事情。

Sam Varshavchik的回答包含了很多好的建议。但是,还有一点值得说明...

配置类的公共 API 将提供一个或多个用于检索配置值的lookup()样式方法。为了确保线程安全,必须确保这些lookup()方法返回基础配置值的深层副本(而不是指向的指针/引用)。例如,如果返回字符串,则返回类型应为 std::string 而不是 const std::string &const char *