Telegram 机器人(Google Cloud 运行 上的 Flask 应用程序)在实例重新加载后停止响应
Telegram bot (Flask app on Google Cloud Run) stops responding after instance reloading
我正在尝试在 Python 上制作我的第一个 Telegram 机器人。我在 Google Cloud 运行 中使用 python-telegram-bot、Flask、运行。
在我的本地机器上一切正常,当我将它(使用 Docker)部署到 Google 云 运行 时,一切也都正常,直到 Google 云 运行 ] 停止实例。这就是我在 Gloud 运行 日志中看到的内容:
[2022-02-23 11:09:24 +0000] [1] [INFO] Handling signal: term
[2022-02-23 11:09:24 +0000] [3] [INFO] Worker exiting (pid: 3)
[2022-02-23 11:09:25 +0000] [1] [INFO] Shutting down: Master
此机器人停止响应后。
我尝试设置一个最小实例数功能(设置一个最小实例数=1)但它没有帮助,机器人在一段时间后停止响应。
这是来自 main.py 的部分代码:
...
@app.route("/")
def main() -> None:
updater = Updater("TOKEN")
dispatcher = updater.dispatcher
conv_handler = ConversationHandler(
entry_points=[CommandHandler('start', start), CommandHandler('menu', menu), CallbackQueryHandler(button)],
states={
START: [
MessageHandler(Filters.regex('^(Default Text)$') & (~ Filters.command), start)
]},
fallbacks=[CommandHandler('cancel', cancel), CommandHandler('menu', menu)],
allow_reentry=True
)
dispatcher.add_handler(conv_handler)
updater.start_polling()
updater.idle()
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
我想问题是只有当我向我的 Google 云 URL 发出 GET 请求时,机器人才会启动: app.route("/") 被触发并且主要功能开始了。如果云 运行 实例停止并且我手动请求我的服务 URL(我从 Google 云 运行 获得,如 https://service-name-xxxxx-xx.a.run.app),机器人将启动再次。这是 Cloud 运行 之后的日志:
[2022-02-23 11:09:24 +0000] [1] [INFO] Handling signal: term
[2022-02-23 11:09:24 +0000] [3] [INFO] Worker exiting (pid: 3)
[2022-02-23 11:09:25 +0000] [1] [INFO] Shutting down: Master
---我手动请求了一项服务url---
[2022-02-23 19:03:21 +0000] [1] [INFO] Starting gunicorn 20.1.0
[2022-02-23 19:03:21 +0000] [1] [INFO] Listening at: http://0.0.0.0:8080 (1)
[2022-02-23 19:03:21 +0000] [1] [INFO] Using worker: gthread
[2022-02-23 19:03:21 +0000] [3] [INFO] Booting worker with pid: 3
2022-02-23 19:03:21,985 - apscheduler.scheduler - INFO - Scheduler started
老实说,我想不出比跟踪实例重启并每次请求 URL 更好的了。
希望得到您的指点,谢谢!
TBF,我不熟悉 Google Cloud 运行,但如果我理解正确的话,重点是你的代码只会在向应用程序发出请求时被调用,即它是那些“无服务器”设置之一 - 对吗?
如果是:updater.start_polling()
所做的是启动一个 long 运行ning 持续获取更新的后台线程。要使用此方法让您的机器人全天候响应 24/7,您的脚本需要 运行 24/7。现在无服务器设置的重点是您的代码仅 运行s 按需 ,因此对于这种托管方法,更合理的方法是仅在您的机器人收到时调用您的代码更新。这可以使用 webhook 而不是长轮询来实现。在关于 AWS Lambda 的 PTB wiki. See also this thread 中有一节,这与 AFAIK 类似。
然而,应该注意像 ConversationHandler
这样的状态逻辑在这样的设置中很难实现:默认情况下 ConversationHandler
在内存中 跟踪当前状态 ,因此信息会在进程关闭时丢失。您可以使用 persistence 来存储数据,但我不确定这在无服务器设置中的效果如何——如果同时进行多个更新,可能会出现竞争条件。
所以另一个想法是切换到不同的托管服务,允许 运行 你的进程 24/7。
免责声明:我目前是 python-telegram-bot
.
的维护者
我正在尝试在 Python 上制作我的第一个 Telegram 机器人。我在 Google Cloud 运行 中使用 python-telegram-bot、Flask、运行。 在我的本地机器上一切正常,当我将它(使用 Docker)部署到 Google 云 运行 时,一切也都正常,直到 Google 云 运行 ] 停止实例。这就是我在 Gloud 运行 日志中看到的内容:
[2022-02-23 11:09:24 +0000] [1] [INFO] Handling signal: term
[2022-02-23 11:09:24 +0000] [3] [INFO] Worker exiting (pid: 3)
[2022-02-23 11:09:25 +0000] [1] [INFO] Shutting down: Master
此机器人停止响应后。
我尝试设置一个最小实例数功能(设置一个最小实例数=1)但它没有帮助,机器人在一段时间后停止响应。
这是来自 main.py 的部分代码:
...
@app.route("/")
def main() -> None:
updater = Updater("TOKEN")
dispatcher = updater.dispatcher
conv_handler = ConversationHandler(
entry_points=[CommandHandler('start', start), CommandHandler('menu', menu), CallbackQueryHandler(button)],
states={
START: [
MessageHandler(Filters.regex('^(Default Text)$') & (~ Filters.command), start)
]},
fallbacks=[CommandHandler('cancel', cancel), CommandHandler('menu', menu)],
allow_reentry=True
)
dispatcher.add_handler(conv_handler)
updater.start_polling()
updater.idle()
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
我想问题是只有当我向我的 Google 云 URL 发出 GET 请求时,机器人才会启动: app.route("/") 被触发并且主要功能开始了。如果云 运行 实例停止并且我手动请求我的服务 URL(我从 Google 云 运行 获得,如 https://service-name-xxxxx-xx.a.run.app),机器人将启动再次。这是 Cloud 运行 之后的日志:
[2022-02-23 11:09:24 +0000] [1] [INFO] Handling signal: term
[2022-02-23 11:09:24 +0000] [3] [INFO] Worker exiting (pid: 3)
[2022-02-23 11:09:25 +0000] [1] [INFO] Shutting down: Master
---我手动请求了一项服务url---
[2022-02-23 19:03:21 +0000] [1] [INFO] Starting gunicorn 20.1.0
[2022-02-23 19:03:21 +0000] [1] [INFO] Listening at: http://0.0.0.0:8080 (1)
[2022-02-23 19:03:21 +0000] [1] [INFO] Using worker: gthread
[2022-02-23 19:03:21 +0000] [3] [INFO] Booting worker with pid: 3
2022-02-23 19:03:21,985 - apscheduler.scheduler - INFO - Scheduler started
老实说,我想不出比跟踪实例重启并每次请求 URL 更好的了。
希望得到您的指点,谢谢!
TBF,我不熟悉 Google Cloud 运行,但如果我理解正确的话,重点是你的代码只会在向应用程序发出请求时被调用,即它是那些“无服务器”设置之一 - 对吗?
如果是:updater.start_polling()
所做的是启动一个 long 运行ning 持续获取更新的后台线程。要使用此方法让您的机器人全天候响应 24/7,您的脚本需要 运行 24/7。现在无服务器设置的重点是您的代码仅 运行s 按需 ,因此对于这种托管方法,更合理的方法是仅在您的机器人收到时调用您的代码更新。这可以使用 webhook 而不是长轮询来实现。在关于 AWS Lambda 的 PTB wiki. See also this thread 中有一节,这与 AFAIK 类似。
然而,应该注意像 ConversationHandler
这样的状态逻辑在这样的设置中很难实现:默认情况下 ConversationHandler
在内存中 跟踪当前状态 ,因此信息会在进程关闭时丢失。您可以使用 persistence 来存储数据,但我不确定这在无服务器设置中的效果如何——如果同时进行多个更新,可能会出现竞争条件。
所以另一个想法是切换到不同的托管服务,允许 运行 你的进程 24/7。
免责声明:我目前是 python-telegram-bot
.