一个简单的一次性改进是使用PyPy而不是标准 CPython 用于长期脚本和守护程序(对于短期脚本,它不太可能有帮助,实际上可能有更长的启动时间)。除此之外,听起来您已经发现了短期系统脚本的最大改进之一,即避免为频繁调用的脚本启动 Python 解释器的开销。
例如,如果您从另一个脚本调用一个脚本并且它们都在 Python 中,那么您绝对应该考虑将另一个脚本作为模块导入并直接调用其函数,而不是使用subprocess
或类似的方法。
我明白这并不总是可以做到这一点,因为一些用例依赖于被调用的外部脚本——例如,Nagios 检查将很难始终保持驻留。您使实际检查脚本成为简单 HTTP 请求的方法似乎足够合理,但我采取的方法是使用被动检查并运行外部服务来定期更新状态。这允许生成检查结果的服务作为守护进程驻留,而不需要 Nagios 为每次检查调用脚本。
另外,请注意您的系统,看看缓慢是否真的是 CPU 过载或 IO 问题。您可以使用实用程序vmstat
来查看您的 IO 使用情况。如果您受 IO 限制,那么优化您的代码不一定会有很大帮助。在这种情况下,如果您正在处理诸如处理大量文本文件(例如日志文件)之类的事情,那么您可以将它们压缩存储并使用 Python 的gzip
模块直接访问它们。这增加了 CPU 负载但减少了 IO 负载,因为您只需要从磁盘传输压缩数据。您还可以使用相同的方法直接以 gzip 格式编写输出文件。
具体恐怕我不是特别熟悉web2py
,但是如果数据的新鲜度不是很关键,你可以研究一下是否容易在前面放一个缓存层。尝试并确保您的服务器和客户端都正确使用条件请求,这将减少请求处理时间。如果他们使用的是后端数据库,您可以调查memcached之类的东西是否会有所帮助。只有当您遇到相当多的请求或每个请求的处理成本很高时,这些措施才可能给您带来真正的好处。
我还应该补充一点,通常以其他方式减少系统负载有时会带来令人惊讶的好处。我曾经有一个运行 Apache 的相对较小的服务器,我发现迁移到 nginx 的帮助非常大——我相信它在一定程度上提高了请求处理的效率,但主要是它释放了一些内存,然后文件系统缓存可以用来进一步提高 IO-绑定操作。
最后,如果开销仍然是一个问题,那么仔细分析您最昂贵的脚本并优化热点。这可能是在改进您的 Python 代码,或者如果您愿意,也可能意味着将代码推送到 C 扩展。通过将数据路径代码推送到 C 扩展中以进行大规模日志处理和类似任务(一次谈论数百 GB 的日志),我获得了一些出色的性能。但是,这是一种繁重且耗时的方法,应该保留给您真正需要速度提升的少数地方。这还取决于您是否有足够熟悉 C 的人来做这件事。