使Perl脚本在Perl中检测单独配置模块中的更改

时间:2009-10-17 15:19:08

标签: perl solaris configuration-files

天儿真好,

我们有一个Perl脚本正在处理来自主要网站的前端服务器的地理定位请求。该脚本是一个代理,提供额外的业务逻辑,解释由COTS产品返回的数据,该产品为给定的IP地址提供数据,例如,国家,连接类型,路由类型,运营商等。

此Geo服务目前正处理COTS后端每秒约1,000个请求的峰值负载。 BTW它实际上是服务5,000请求p.s.来自其直接位于代理层之前的专用负载均衡/缓存层。

我最近不得不修改此代理的行为,以允许我们在网站上看到的新类型的连接,这会导致一些问题。

脚本的原始版本,而不是我的设计! btw,是使用脚本本身中的配置项和单独的Perl片段中的其他项混合构建的。正如在我的更改的同行评审中正确指出的那样,我们应该将所有配置项迁移到单独的位置,而不是继续使用嵌入式和单独的配置项的混合。

现在我想更进一步,将所有配置项(作为单独的Perl哈希值创建)放入一个配置文件中。

目前,我们必须停止并重新启动整个应用程序以重新加载新的配置项,考虑到流量级别,即使在两个独立的数据中心有四个代理实例,所以我们还是有点不方便从来没有真正失去服务。

我怀疑我将不得不求助于保留计时器,或者可能是请求计数器,并对相关配置文件执行统计。或者甚至可以为配置文件配置一个TTL,并且每隔十分钟左右重新加载一次。

但有没有办法让Perl自动重新加载以前加载的文件的较新版本?我正在考虑Apache mod_perl模块提供的行为。

欢呼声,

5 个答案:

答案 0 :(得分:5)

罗布,几点:

1)最好将配置阅读器抽象为API,而不是直接从Perl哈希读取。这样,对该API的任何调用都可以反过来决定需要对配置做什么(例如,计时器已启动?配置文件时间戳是否发生了变化?)。

与往常一样,这有一个额外的好处,允许您稍后重新设计配置(perl has => xml =>数据库),而无需更改任何软件。

2)看到它是服务器,我还建议通过特殊请求类型进行按需配置重新加载功能。这允许您通过向服务器发送命令而不是反弹来强制配置重新加载(例如,在更新配置文件之后)。

顺便说一下,如果你遵循#1就很容易做到#2,因为“reload config”处理程序需要做的就是重置“config需要在下一个config API调用上重新加载”标志。

3)如果您坚持将配置作为没有API的哈希(例如,出于性能原因消除API子程序调用,这似乎是合理但不太可能有用),那么您需要将配置置于静态你的类中的变量,并让该类提供“set new config”方法。然后服务器将设置一个计时器,并在计时器调用(或从#2接收“reload config”命令)时检查配置文件的时间戳和/或校验和是否与上次调用时不同并重新加载。

答案 1 :(得分:3)

如果您使用的是最新版本的Linux,则始终存在inotify路径。这意味着您可以在将配置写入磁盘后立即重新加载配置。查看Linux-Inotify。其他平台也有FAM

答案 2 :(得分:2)

在Unix类型计算机上解决此类问题的传统方法是服务器程序在收到signal时重新加载其配置。例如,Apache documentation表示三个信号对服务器具有特殊含义:TERM告诉服务器关闭,HUP强制立即重启,USR1请求正常重新加载配置文件。如果您在支持信号的环境中工作,这种功能可以相对简单地内置到您的程序中。

答案 3 :(得分:1)

总是可以选择将配置移动到数据库中,并使用DBI和数据库触发器使其成为事件驱动而不是轮询。

答案 4 :(得分:0)

@DVK,哦,好好打电话1)我没想过在配置上方添加额外的抽象层。我想将它保留为原始Perl哈希值的优点是不需要转换层。我会考虑所涉及的权衡。

关于第2点)我们发现Perl中的信号处理存在一些瑕疵,使得它不是HUP,因此我们在站点范围内正式弃用了Perl信号HUP。

但我真的很喜欢你想要一个强制重新加载的特殊查找命令!如果你不介意,我会用它。也许使用“GET 127.0.0.1”,因为这可能不会从外面传来!注:我们的地理协议的最新版本是基于http的,因此我们可以轻松地从浏览器查询服务。

谢谢! \o/