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

如何在Pycord Discord机器人中捕获Heroku的SIGTERM信号?

在Heroku上为Discord机器人捕获SIGTERM信号并保存数据

Heroku在重启或停止dyno时,会先发送SIGTERM信号,随后等待30秒再发送SIGKILL强制终止进程。你可以通过监听该信号,执行数据保存逻辑后优雅退出。以下是主流语言的实现方案:

Node.js(Discord.js)实现

const { Client } = require('discord.js');
const client = new Client({ intents: [/* 填写你的机器人所需意图 */] });

// 定义数据保存逻辑
async function saveCriticalData() {
  console.log('开始保存关键数据到数据库');
  // 替换为你的实际数据库操作,比如:
  // await yourDb.collection('userSessions').bulkWrite(yourCachedData);
}

// 监听SIGTERM信号
process.on('SIGTERM', async () => {
  console.log('收到SIGTERM信号,启动优雅关闭流程');
  
  // 停止Discord客户端的事件监听,不再处理新请求
  client.destroy();
  
  // 执行数据保存,确保操作在30秒内完成
  await saveCriticalData();
  
  console.log('数据保存完成,程序退出');
  process.exit(0);
});

// 机器人登录
client.login('你的机器人令牌');

Python(discord.py)实现

import discord
import asyncio
import signal
import sys

client = discord.Client(intents=discord.Intents.all())

# 定义数据保存逻辑
async def save_critical_data():
    print("开始保存关键数据到数据库")
    # 替换为你的实际数据库操作,比如:
    # await your_db.update_many({}, {"$set": your_cached_data})

async def handle_sigterm():
    print("收到SIGTERM信号,启动优雅关闭流程")
    await client.close()  # 关闭Discord客户端连接
    await save_critical_data()
    print("数据保存完成,程序退出")
    sys.exit(0)

def sigterm_handler(signum, frame):
    # 将同步信号处理转为异步任务
    asyncio.create_task(handle_sigterm())

# 注册SIGTERM信号处理器
signal.signal(signal.SIGTERM, sigterm_handler)

@client.event
async def on_ready():
    print(f"机器人已登录:{client.user}")

client.run("你的机器人令牌")

关键注意事项

  • 数据保存操作必须快速完成,Heroku仅提供30秒窗口,超时会被强制终止
  • 避免在保存逻辑中执行阻塞或耗时操作(如大量数据同步)
  • 测试时可通过heroku ps:restart触发重启,用heroku logs --tail查看信号捕获和数据保存日志
  • 确保数据库连接在信号触发时处于可用状态,避免因连接问题导致保存失败

内容的提问来源于stack exchange,提问作者Luca

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:31:08