![扩展 Python CGI 脚本](https://linux22.com/image/562147/%E6%89%A9%E5%B1%95%20Python%20CGI%20%E8%84%9A%E6%9C%AC.png)
我在 384kbps ADSL 上的四核 Ubuntu 服务器上运行 Apache。用户通过 Web 表单上传文件,并由作为 CGI 脚本运行的各种 Python 程序处理。有些脚本占用大量 CPU,以 100% 的负载(在一个核心上)运行几分钟;这些脚本会将结果通过电子邮件发送给用户,因此 HTTP 会话不会保持打开状态。有些脚本需要上传较大的文件(总共几 MB)。目前,使用率非常低,每天只有少数几次点击,而且很少有用户同时使用这些服务。我需要在中期内向更多用户提供这些服务。
我怀疑我构建的基础设施不易于扩展。例如,一个用户要求我允许将多个文件上传到 CPU 密集型程序。这意味着机器将在更长的时间内处于繁忙状态。如果另一个用户也将多个文件上传到同一个脚本,机器可能会在更长的时间内变得非常繁忙。
我知道这里不允许提出讨论类型的问题,所以我想问以下具体问题:
在使这些服务可扩展时,我需要考虑哪些策略或方法——也就是说,我是否需要彻底重新考虑基础设施?
例如,如果我不做任何更改,并且 10 个人每人将 10 个文件上传到 CPU 密集型程序,那么 CGI 脚本创建的所有 10 个线程是否都能顺利(尽管速度很慢)地处理所有 10 个输入文件?让服务器以 100% 的 CPU 使用率运行一两个小时或三个小时是否“安全”?
答案1
如果你的 python 写得很好,并且模块化程度很高,那么它应该不会太糟糕。
你需要做的是调查芹菜,并将其作为作业队列。
当用户提交文件进行处理时,Celery 会将其排队,然后在资源可用时在同一台服务器上或由工作节点进行处理。Celery 通常由 RabbitMQ 或 Redis 作为消息代理(实际队列服务器)支持,这些服务器相对容易扩展。
至于“作业完成”回调,有很多不同的选项可用,你仍然可以使用电子邮件,或者你可以查看类似的服务推进器将通知发送回提交用户的浏览器。
实际上,服务器的设计运行 CPU 负载为 80-90%。我的意思是,这就是您投入的电力获得最大利用率的地方(有点)。
不过我怀疑你是在家里托管这个(因此 ADSL 上行速度很慢),而且它实际上可能只是一台重复使用的台式电脑,不适合用于服务器类型的工作周期和加载。
答案2
首先,您应该考虑WSGI
为您的应用程序使用该接口,然后考虑实现一些异步事件驱动库,Celery
或者gevent
将您的应用程序日志安排到任务中。
CGI
是从内存和灵活性角度调用外部代码的最古老和最无效的方式,重新考虑您的项目以使用任何 python 微框架(例如bottle.py
或flask
),这将为您提供一个更加状态化的环境,您可以将逻辑(您的 python 代码)连接到该环境以使用前面提到的库。