如何通过API关闭Heroku Web Dyno?关闭后自动重启问题求助
问题分析与解决方案
核心原因
Heroku的web类型dyno受平台自动监控,只要应用配置了web进程(比如Procfile里定义了web: ...启动命令),平台会默认保证该进程始终运行——哪怕你通过API停止单个dyno,Heroku也会立刻重启新dyno维持进程数量,这就是停止后马上重启的根本原因。
另外你的代码存在逻辑漏洞:不管dyno是idle还是up状态,都会执行停止请求,因为停止dyno的代码没有被包裹在if statecheck["state"] == "idle"的分支里。
正确解决方案
要彻底停止web进程,需通过Heroku API将web进程的数量缩放到0,而非停止单个dyno。同时修正代码逻辑,仅在dyno处于idle状态时执行操作。
修正后的代码
import requests # 替换为你的Heroku API Token heroku_api_token = "Bearer ENTERAPITOKENHERE" app_name = "rockosmodernapp" # 通用请求头 headers = { 'Accept': 'application/vnd.heroku+json; version=3', 'Authorization': heroku_api_token, 'Content-Type': 'application/json' } # 检查web.1 dyno的状态 state_response = requests.get(f(f"https://api.heroku.com/apps/{app_name}/dynos/web.1", headers=headers) statecheck = state_response.json() print(statecheck) if statecheck["state"] == "idle": print("检测到web进程空闲,开始停止web应用") # 缩放web进程到0,彻底停止所有web dyno scale_payload = {"quantity": 0, "size": "hobby"} # size替换为你实际使用的dyno规格 scale_response = requests.patch(f"https://api.heroku.com/apps/{app_name}/formation/web", headers=headers, json=scale_payload) print(f"缩放请求响应状态: {scale_response.status_code}, 原因: {scale_response.reason}") elif statecheck["state"] == "up": print("应用仍在运行,15分钟后再检查是否空闲") else: print(f"当前dyno状态: {statecheck['state']}")
关键说明
- 使用
PATCH /apps/{app-name}/formation/web接口缩放web进程数量,设置quantity: 0会彻底停止所有web类型dyno,平台不会自动重启。 size参数需和你当前使用的dyno规格一致(比如hobby、standard-1x等)。- 修复了原代码逻辑错误:仅当dyno处于idle状态时才执行停止操作。
验证结果
执行脚本后,可通过两种方式确认结果:
- Heroku控制台中
web进程数量会显示为0,无运行中的dyno。 - 调用API
GET https://api.heroku.com/apps/{app-name}/formation/web,查看返回结果的quantity字段是否为0。
内容的提问来源于stack exchange,提问作者PythonKiddieScripterX
相关产品推荐
相关产品推荐

