使用Perl脚本检测另一个Perl配置模块的更改

3

您好,

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

这个Geo服务目前正在处理COTS后端每秒约1,000个请求的高峰负载。顺便说一下,它实际上从专用的负载平衡/缓存层中直接提供5,000个请求每秒。

最近我不得不修改这个代理的行为,以允许新类别的连接发生在网站上,这引起了一些问题。

脚本的原始版本不是我的设计!顺便说一句,在同行评审我的更改时,他们很正确地指出,我们应该将所有配置项迁移到单独的配置文件中,而不是继续使用混合嵌入和单独的配置项。

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

目前,我们必须停止并重新启动整个应用程序才能重新加载新的配置项,考虑到流量水平,这有点不方便,尽管代理层在两个不同的数据中心中有四个实例,所以我们从未真正失去服务。

我怀疑我将不得不使用计时器或请求计数器,并对相关的配置文件执行stat操作。或者甚至为配置文件配置一个TTL,每十分钟重新加载它一次。

但是是否有一种方法可以使Perl自动重新加载它先前加载过的文件的更新版本?我想到了类似于Apache mod_perl模块提供的行为。

谢谢!

5个回答

5

Rob,有几点需要注意:

1)最好将配置读取器抽象成一个API,而不是直接从Perl哈希表中读取。这样,对该API的任何调用都可以决定如何处理配置(例如,计时器是否到期?配置文件时间戳是否更改?)。

总之,这种方法的另一个好处是,即使稍后重新设计配置(perl => xml => 数据库),也无需更改任何软件。

2)考虑到它是服务器,我还建议通过特殊请求类型实现按需配置重载功能。这样,您可以通过向服务器发送命令来强制重新加载配置(例如,在更新配置文件后),而无需反弹服务器。

顺便说一下,如果遵循第1点,#2非常容易实现,因为“重新加载配置”处理程序只需要重置“下一个配置API调用需要重新加载配置”的标志即可。

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


1
P.S. 我猜有人可能会建议使用绑定哈希(tied hashes),但考虑到你们的规模,我对直接绑定文件的哈希性能存在顾虑。 - DVK

3

如果你使用的是较新版本的Linux系统,可以采用inotify来实现配置文件的重新加载。这意味着只要配置文件被写入磁盘,就可以立即重新加载配置。请参阅Linux-Inotify。其他平台可使用FAM


2
在类Unix系统中,解决这种问题的传统方法是当服务器程序收到一个信号时重新加载其配置。例如,Apache文档指出三个信号对服务器有特殊含义:TERM告诉服务器关闭,HUP强制立即重启,USR1请求优雅地重新加载配置文件。如果您正在使用支持信号的环境,则可以相对轻松地将此类功能构建到您的程序中。

@Tim,我们在使用Perl信号处理方面遇到了很多不稳定性问题,因此我们几乎已经放弃在整个网站中使用它。 - Rob Wells
顺便提一下,为了更清晰明了,已添加Solaris 10标签。 - Rob Wells

1

总是有把配置文件移动到数据库并使用DBI加数据库触发器使其事件驱动而不是轮询的选项。


@Howard,感谢您的建议,但我现在正在考虑将业务逻辑作为一个单独加载的模块,就像lbnamed负载平衡名称服务器一样。 - Rob Wells

0

@DVK,噢,你的第一点提醒很好。我没有考虑在配置上面添加额外的抽象层。我想保留它作为原始的Perl哈希表的优点是不需要转换层。我会考虑涉及到的权衡。

至于第二点,我们发现Perl信号处理存在一些不稳定性,导致它不能很好地处理HUP,因此我们已经在全站范围内正式弃用了Perl信号HUP。

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

谢谢!\o/


1
如果你正在自己实现HTTP,那么考虑使用全新的方法而不是“神奇”的GET。例如 RESTART / HTTP/1.1,当然,一定要确保进行身份验证... - hobbs
@hobbs,谢谢你的提示。当我们解析传入的请求时,我可能会这样做。这些地理请求受到非常严格的 ACL 限制,只有来自特定主机的请求才会被处理。我看到的唯一问题是在未来,当我们考虑用在 Apache 下运行的专用模块替换 Perl 经纪人时。 - Rob Wells
2
#2,我指的是一个特殊命令(通常是全新的命令,但如果必要的话,某些现有命令的巫术值当然也是可行的)。绝对不是像Apache那样的系统信号。 - DVK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接