部署在Digital Ocean的Discord.js机器人报memory access out of bounds错误
问题根因分析
这个错误来自项目依赖的opusscript库的WebAssembly编译版本,属于该库的已知稳定性问题,WebAssembly实例长时间运行处理音频流时会出现内存越界访问。本地和Heroku未触发是因为不同平台的依赖安装默认配置、进程内存限制、运行时长阈值存在差异,Digital Ocean的Linux环境下该bug的触发概率更高。
解决方案
按优先级从高到低排列:
- 替换Opus解码库(最彻底的解决方案)
opusscript是纯JS/WASM实现的Opus编解码库,稳定性远低于原生编译版本。直接卸载opusscript,安装Discord官方维护的原生编解码库即可,无需修改业务代码,DisTube会自动优先调用该库:npm uninstall opusscript npm install @discordjs/opus - 降级opusscript到稳定版本
如果你坚持使用opusscript,可以降级到无已知内存问题的0.0.7版本:npm install opusscript@0.0.7 - 优化进程内存配置
如果你使用的是Digital Ocean 512MB内存的低配Droplet,音频解码的内存占用很容易触达实例内存上限,可选择两种优化方案:- 升级到1GB及以上内存的Droplet
- 配置PM2内存自动重启阈值,避免进程崩溃:
pm2 start 你的入口文件.js --max-memory-restart 400M - 修复代码逻辑缺陷
你当前的play命令存在逻辑漏洞,未将distube.play的调用包裹在command == "play"的判断范围内,会导致任意命令只要用户在语音频道就会触发播放请求,异常请求增多会加重内存负担,建议调整为:if (command == "play") { if (!message.member.voice.channel) { return message.channel.send("You are not in a voice channel.") } distube.play(message, args.join(" ")); }
内容的提问来源于stack exchange,提问作者BlurryMeal
相关产品推荐
相关产品推荐

