Discord机器人报heartbeat blocked错误,命令执行无响应求助
解决Discord机器人心跳阻塞(heartbeat blocked)无响应问题
问题本质
discord.gateway: shard id none heartbeat blocked for more than 10 seconds 这个报错的核心是:机器人的事件循环被同步阻塞操作占用超过10秒,导致无法按时向Discord网关发送心跳包,网关判定机器人离线,最终表现为机器人无响应。
从你提供的代码来看,主逻辑本身没有明显阻塞点,问题大概率出在你加载的 cogs.whitelist 扩展中。
针对性解决方案
1. 排查并修复扩展中的阻塞代码
检查 cogs/whitelist.py,如果存在以下类型的同步代码,必须修改为异步或放到线程池执行:
- 同步网络请求(如用
requests而非aiohttp) - 长时间循环计算
- 大文件同步读写
示例1:将同步网络请求改为异步
# 错误写法(同步阻塞) import requests @commands.command() async def check_whitelist(self, ctx, user): response = requests.get(f"http://your-api.com/whitelist/{user}") await ctx.send(response.text) # 正确写法(异步非阻塞) import aiohttp @commands.command() async def check_whitelist(self, ctx, user): async with aiohttp.ClientSession() as session: async with session.get(f"http://your-api.com/whitelist/{user}") as response: result = await response.text() await ctx.send(result)
示例2:用线程池处理必须同步的代码
如果依赖的库不支持异步,用 asyncio.to_thread 把同步操作移到线程执行:
import asyncio import requests @commands.command() async def check_whitelist(self, ctx, user): result = await asyncio.to_thread(requests.get, f"http://your-api.com/whitelist/{user}") await ctx.send(result.text)
2. 临时隔离测试定位问题
先注释掉加载扩展的代码,验证主机器人是否正常工作:
async def setup_hook(self): # for ext in self.cogslist: # await self.load_extension(ext) pass
如果此时发送 .hello 命令机器人能正常回复,说明问题100%出在 whitelist 扩展中,集中排查即可。
3. 优化初始化逻辑(可选)
如果扩展的 __init__ 或 setup 函数中存在同步阻塞操作,也要将其改为异步或移到线程,避免在机器人启动阶段就阻塞事件循环。
4. 分片部署(针对多服务器机器人)
如果你的机器人加入了大量服务器,启用分片可以分散负载,降低单分片事件循环过载的概率:
class Client(commands.Bot): def __init__(self): super().__init__( command_prefix=commands.when_mentioned_or('.'), intents=discord.Intents().all(), shard_count=2 # 根据服务器数量调整分片数 ) self.cogslist = ["cogs.whitelist"]
验证标准
修改后运行机器人,发送 .hello 命令能正常收到回复,同时日志不再出现 heartbeat blocked 报错,即说明问题解决。
内容的提问来源于stack exchange,提问作者AntiNano
相关产品推荐
相关产品推荐

