【问题标题】:read many time config file or use gen_server status?多次读取配置文件或使用 gen_server 状态?
【发布时间】:2011-08-31 21:20:02
【问题描述】:

我使用 gen_server 和 gen_fsm 实现了一个 otp 系统。对于软件运行所需的一些值,需要读取一个配置文件,例如:

{values, [value1, value2, value3]}.

我使用宏来提取其中一个值

define(VALUES, my_utility:get_conf_value(values)). 

问题如下:由于 ?VALUES 可能会被非常频繁地调用,因此配置文件会被解析多次,我是否应该将 ?VALUES 嵌入到我的 gen_fsm 的 gen_server 的状态中,并在我随时调用时将其提取出来需要它?

事实上,我真的很欣赏之前的实现,因为只需更改配置文件中的值即可更改软件的行为,而无需更改或调用任何#state{}。

您更喜欢哪种解决方案?

【问题讨论】:

    标签: erlang configuration-files erlang-otp


    【解决方案1】:

    解决方案将取决于您的要求。性能与“正确性”。

    一种可能的解决方案是将配置保持在进程状态并定期重新读取(检查文件修改时间是否已更改)。这可能是两个世界之间的一个很好的折衷方案。

    总结:

    • 每次都从文件中重新读取:始终是最新的,但会因不必要的 IO 而变慢
    • 按间隔重新读取,以进程状态存储:读取速度快,但滞后
    • 手动重读:阅读速度快,但滞后,需要手动触发
    • 读取一次并存储在进程状态:快速读取,需要重启才能更新

    未考虑的要求:安全性、稳定性(配置文件损坏?)

    【讨论】:

    • 正是我的意思..如果配置文件中出现错误,系统将崩溃...安全性如何?此外,避免重新启动的一种解决方案可能是调用服务器以更新值...
    • 安全性:如果有人可以访问文件系统并能够操作配置文件会怎样。
    • 解决文件损坏的一种方法是在重新读取文件时验证内容,如果文件损坏则忽略它(并将一些错误输出到日志中,以便观察问题)。跨度>
    【解决方案2】:

    这实际上是一个比人们最初想象的要困难得多的话题。例如:

    • 如何更改配置?
    • 如果发生变化,是否有任何流程需要通知?
    • 您是否将配置存储在某个中间进程/状态中?这需要清除吗?
    • 您如何确保每个人在所有不同节点上的所有不同进程中看到相同的配置?
    • 或者即使配置不正确,您的系统也能正常工作?
    • 配置访问频率如何?
    • 您在那里存储什么数据?

    因此,分析您当前的解决方案:

    • 如果你关心这些问题,每次你需要一个值时解析配置文件会太慢并产生太多垃圾
    • 向 gen_server 询问值也可能太慢,具体取决于您的使用案例。
    • 如果您需要进行多次查找,gen_server 也可能会过载
    • 如果数据很大,可能会在 gen_server 和您的进程之间进行复制
    • 如果您的应用程序在多台机器上运行并且您不能容忍配置不一致,您必须协调更新以尽可能接近同一时间(如果您使用我能想到的任何解决方案,您都可以做到这一点)关心一致性)

    另一种解决方案是将配置存储为代码。例如,您可以有一个特殊的配置模块,您可以使用解析转换或生成实际的源文件来创建它。使用此解决方案,配置值驻留在 VM 的常量池中,并且获取它们会产生尽可能少的垃圾(取决于您以后如何处理数据)。

    【讨论】:

      【解决方案3】:

      我个人认为最好的解决方案是将配置作为模块。好处是:

      • 真的非常快
      • 可以通过热代码更改进行更改
      • 可以从任何形式的配置文件格式机器生成
      • 编译和热代码交换只需“正确”配置即可免费为您提供原子更新

      P.S.:请参阅网络模块加载(shell 中的又名 nl/1)以了解集群范围的配置更改。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-10
      • 1970-01-01
      • 2012-04-03
      • 2019-04-22
      • 2011-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多