You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Heroku部署Selenium抓取Messenger数据触发MySQL max_questions错误

错误根因

你遇到的报错是MySQL对单用户的每小时查询次数限制触发的,和Facebook登录授权只是时间上的巧合:

  • 你的repeater函数是无终止条件的递归调用,没有任何等待间隔,程序启动后会无限制高频发起SELECT * FROM senders查询
  • 免费MySQL实例(比如Heroku默认提供的ClearDB免费层)的max_questions默认值就是3600次/小时,你的高频查询会在几秒内就把额度耗尽,触发报错
  • 同时递归无终止的写法还会导致调用栈持续增长,很快就会触发栈溢出导致进程崩溃
解决方案

按优先级执行以下优化即可:

  1. 替换递归逻辑为带休眠的循环,先从根源降低查询频率,同时避免栈溢出:
def repeater():
    while True:
        senders = [sender['name'] for sender in database.execute(text("SELECT * FROM senders")).fetchall()]
        # 原有处理新消息的逻辑
        time.sleep(10) # 按需调整间隔,10秒查询1次的话每小时仅请求360次,远低于3600的限制
repeater()
  1. 增加本地缓存,进一步消除不必要的查询:仅在程序启动时全量拉取一次发送者列表存在本地内存中,后续检测到新发送者入库时再更新本地缓存,不需要每次循环都查库:
# 初始化时仅查询1次
cached_senders = set(sender['name'] for sender in database.execute(text("SELECT * FROM senders")).fetchall())

def repeater():
    while True:
        # 从Messenger拉取新消息、拿到发送者的原有逻辑
        new_sender = 从消息中提取的发送者名称
        if new_sender not in cached_senders:
            # 新发送者写入数据库
            database.execute(text("INSERT INTO senders (name) VALUES (:name)"), {"name": new_sender})
            # 更新本地缓存
            cached_senders.add(new_sender)
        time.sleep(10)
repeater()
  1. 如果业务确实需要更高的查询配额,可以升级你的MySQL实例规格,后台调整max_questions参数到更高值即可。
  2. 临时恢复服务可以等待1小时,MySQL的max_questions是按小时滚动计数,周期结束后配额会自动重置。

内容的提问来源于stack exchange,提问作者Jae Woo Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 23:54:03