1

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

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

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

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

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

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

您更喜欢哪种解决方案?

4

3 回答 3

2

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

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

概括:

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

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

于 2011-05-24T12:15:16.860 回答
2

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

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

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

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

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

于 2011-05-24T12:36:18.143 回答
2

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

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

PS:有关集群范围的配置更改,请参阅网络模块加载(shell 中的又名 nl/1)。

于 2011-05-24T16:12:55.413 回答