用 Heroku 托管 Flask App 时,每一个连接最多保持 30 秒,而且这个限制是没法取消的。30 秒的时间对于一些爬虫类 API 可能就不太够了,经常会遇到超时被强制结束进程的情况。为了让这类耗时较长的 API 正常运行,我们可能需要用一些奇技淫巧。
思路
经测试,Heroku 虽然会直接中止连接进程,但通过 subprocess
运行的后台脚本是不会被中止的。因此我们可以:
API 被访问 → 启动前台后台双爬虫 → 后台爬虫将数据写入数据库(MongoDB、LeanCloud,等等)→ 若前台没超时,那皆大欢喜 → 若前台超时了,下一次再访问 API 就直接从数据库里面取,不需要再爬一次了。
之前失败的尝试
之前以为 Heroku 只是超时断开连接,但程序还是接着跑,于是就在 app.py
开一个全局字典变量存数据,结果发现数据存不进去,估计是断开连接的同时也把进程终止了。
涉及的库(Libraries)
用到的库有:
- subprocess:启动后台脚本
- click:命令行支持
- 数据库支持
目录结构
本例的,目录结构如下:
1 | ./ |
代码修改
app.py 中返回数据的 API:
1 | if 数据库内有对应数据: |
background_job.py:
1 |
|
一些可以做的改进
- API 中添加强制刷新数据库数据的接口
- 数据库数据用多少次之后/超过多少时间后自动作废