使用discord.js开发机器人时user cache用户缓存骤降如何修复
问题原因
discord.js v13及以上版本受Discord网关意图限制、默认缓存策略调整影响,默认不会预加载全量服务器用户缓存,仅会缓存机器人自身、触发过交互/发送过消息的少量用户,所以会出现缓存数量远低于实际用户数的问题。
修复步骤
1. 开启必要的网关权限与意图
- 首先登录Discord开发者平台,进入你的机器人应用页,切换到「Bot」选项卡,找到Privileged Gateway Intents区域,开启
Server Members Intent权限。 - 初始化Client实例时,声明所需的网关意图,示例代码如下:
const { Client, GatewayIntentBits } = require('discord.js'); const client = new Client({ intents: [ GatewayIntentBits.Guilds, // 必要的服务器基础意图 GatewayIntentBits.GuildMembers, // 成员读取意图,必须和后台开启的权限对应 GatewayIntentBits.GuildMessages, // 如果需要监听消息触发缓存可以添加 GatewayIntentBits.MessageContent // 如需读取消息内容可以添加 ] });
2. 调整缓存策略
你可以修改Client初始化时的缓存配置,调整用户/成员的缓存规则,示例如下:
const { Client, GatewayIntentBits, Options } = require('discord.js'); const client = new Client({ intents: [/* 上面的意图配置保持不变 */], // 缓存配置,这里设置缓存所有服务器成员,可根据需求调整限制 makeCache: Options.cacheWithLimits({ GuildMemberManager: Infinity, // 缓存所有服务器成员,也可以填数字限制最大缓存数 UserManager: Infinity // 缓存所有用户 }) });
3. 启动时预拉取全量成员
如果需要机器人启动时就加载所有服务器的成员到缓存,可以在ready事件中添加成员拉取逻辑,示例代码:
client.on('ready', async () => { // 遍历所有已加入的服务器,拉取全量成员 for (const guild of client.guilds.cache.values()) { try { await guild.members.fetch(); } catch (err) { console.log(`拉取服务器 ${guild.name} 成员失败:`, err); } } // 此时再打印缓存数量就会符合预期 console.log(`Logged in as ${client.user.tag}!`); console.log(`Watching ${client.guilds.cache.size} servers!`) console.log(`Watching ${client.users.cache.size} users!`) console.log(`Watching ${client.channels.cache.size} channels!`) });
注意事项
- 拉取全量成员会触发Discord API速率限制,如果你的机器人加入的服务器总成员数超过10万,不建议一次性全量拉取,可按需拉取指定服务器的成员。
- 全量缓存会占用更多内存,可根据实际需求调整
cacheWithLimits的数值,不需要全量缓存的话可以设置合理的上限。
内容的提问来源于stack exchange,提问作者RG2N
相关产品推荐
相关产品推荐

