ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

eggjs 报错 Warning: Current Server Discovery and Monitoring engine is deprecated 怎么处理?TaoToken 统一 Key

eggjs 报错 Warning: Current Server Discovery and Monitoring engine is deprecated 怎么处理?TaoToken 统一 Key 1. eggjs 连接 MongoDB 时那条 deprecated 警告到底在说什么你启动 eggjs 项目控制台刷出这么一行Warning: Current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor项目还能跑接口也还能返回数据但这条黄色警告一直挂在那儿看着难受。它是什么简单说这是 MongoDB 官方 Node.js 驱动在告诉你你正在用的那套「服务器发现与监控」老引擎要退役了请改用新的统一拓扑引擎。翻译成人话就是——你连数据库的方式没毛病但底层用的是一套即将被删掉的旧机制官方建议你显式打开新开关useUnifiedTopology: true。这条警告的触发点几乎都在 mongoose 这一层。eggjs 本身不直接连 MongoDB它通过egg-mongoose插件把 mongoose 挂到 app 上mongoose 再去调 MongoDB 驱动。老版本 mongoose大致 5.x 早期默认用的是旧引擎驱动检测到你没传useUnifiedTopology就打印这条警告。所以你要改的不是 eggjs 的启动逻辑也不是 MongoDB 服务端配置而是egg-mongoose传给 mongoose 的连接选项。适合谁看正在用 eggjs egg-mongoose 做后端、本地或测试环境连 MongoDB 时被这条警告刷屏的同学。如果你用的是其他语言或其他 ORM处理位置不一样但思路一致——找到构造 MongoClient 时传 options 的地方把useUnifiedTopology打开。我试过在几个 egg 项目里复现只要config.mongoose.options里没有这个字段警告必现加上之后重启控制台立刻干净。下面按「先定位、再配置、后验证」的顺序走一遍顺带把通过统一 Key 通道验证请求链路的做法也串起来方便你在多服务、多环境的项目里统一管理连接与调用凭证。先明确一点这条警告不影响功能但它是技术债的信号。MongoDB 驱动 4.x 之后旧引擎相关代码逐步移除等到你升级 mongoose 大版本时如果配置没跟上可能从「警告」直接变成「连接失败」。所以现在花五分钟改掉比将来半夜排障划算。2. 用 TaoToken 统一 Key 打通配置与验证链路的前置准备在动手改config.default.js之前先把「验证链路」这件事想清楚。很多同学改完配置只知道重启看警告消没消但项目里往往不止一个服务要连数据库、调模型、访问外部 API凭证散落在各个.env、config文件里时间一长就乱。这里引入一个统一入口的思路把需要 Key 的调用集中到一处管理配置项只引用统一通道。TaoToken 在这里扮演的就是这个统一 Key / API 通道的角色。它的官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 这个地址不加 UTM 参数直接用于代码里的 Base URL。你可以在控制台里创建和管理 Key然后让 eggjs 项目通过这个统一通道去调用模型对话、编码辅助等能力而不是每个服务各配一套。具体到本篇场景MongoDB 连接本身不需要 TaoToken但「验证请求链路」这一步会用到。我的做法是数据库连接配置归数据库外部 API 调用归统一通道两者在config.default.js里分开写互不干扰。这样你排查 MongoDB 警告时不会因为 Key 配置混乱而误判。前置准备分三步。第一步拿到统一 Key。打开控制台页面 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 登录后进入 API Keys 管理页 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 新建一个 Key 并复制保存。这个 Key 就是你后续所有需要鉴权的调用凭证。第二步确认你要调用的模型 ID。不同场景用的模型不一样验证链路时随便选一个可用的即可比如做对话验证就用模型对话页 https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 里列出的模型。记住这个 Model ID配置里要写。第三步把 Base URL、Key、Model ID 这三件套准备好。无论你后面是用 Cline、Claude Code 还是自己写请求配置项永远是这三个Base URL 填https://taotoken.net/apiKey 填刚创建的Model ID 填你选的。这三件套在 eggjs 里可以放进config.default.js的mongoose同级位置也可以放进环境变量看你项目规范。注意MongoDB 的连接配置和 TaoToken 的 API 配置是两码事别混在同一个 options 对象里。前者给 mongoose后者给你自己的 HTTP 客户端或 SDK。前置做完你手里应该有一个可用的 Key、一个 Base URL、一个 Model ID。接下来进入正题改 egg-mongoose 的连接配置。3. 可复制的 egg-mongoose 连接配置与 useUnifiedTopology 开启对比核心改动就一个文件config/config.default.js。egg-mongoose 读取的是config.mongoose这个配置对象它会被透传给 mongoose 的connect方法。你要做的就是在options里加上useUnifiedTopology: true。先看改之前的典型配置很多人是这么写的// config/config.default.js 改之前 exports.mongoose { url: mongodb://127.0.0.1:27017/userLog, options: {}, };options是空的mongoose 用默认值去连旧引擎被启用警告就来了。改之后// config/config.default.js 改之后 exports.mongoose { url: mongodb://127.0.0.1:27017/userLog, options: { useUnifiedTopology: true, }, };就这一行。重启 eggjs警告消失。如果你用的是带认证的连接串写法一样只是 url 里带上用户名密码// config/config.default.js 带认证 统一拓扑 exports.mongoose { url: mongodb://appUser:yourPassword127.0.0.1:27017/userLog?authSourceadmin, options: { useUnifiedTopology: true, }, };生产环境通常还会配连接池和超时一并给你一个较完整的片段// config/config.default.js 生产可用片段 exports.mongoose { url: process.env.MONGODB_URL || mongodb://127.0.0.1:27017/userLog, options: { useUnifiedTopology: true, useNewUrlParser: true, maxPoolSize: 10, serverSelectionTimeoutMS: 5000, socketTimeoutMS: 45000, }, };这里useNewUrlParser和useUnifiedTopology经常成对出现前者处理连接串解析后者处理拓扑引擎。mongoose 6 之后这两个选项的默认行为变了但显式写上不会有副作用反而让配置意图更清晰。如果你项目里同时要调外部 API把 TaoToken 的三件套也放进配置和 mongoose 平级// config/config.default.js 数据库 统一通道并存 exports.mongoose { url: mongodb://127.0.0.1:27017/userLog, options: { useUnifiedTopology: true, }, }; exports.taoToken { baseURL: https://taotoken.net/api, apiKey: process.env.TAOTOKEN_API_KEY, model: your-model-id, };注意apiKey从环境变量读别硬编码进仓库。baseURL就是前面说的 API 地址不带任何查询参数。开启前后对比用表格看得更清楚对比项未开启 useUnifiedTopology开启 useUnifiedTopology控制台输出每次启动打印 deprecated 警告无警告使用的拓扑引擎旧版 Server Discovery and Monitoring新版 Unified Topology未来兼容性驱动升级后可能连接失败与新版驱动行为一致配置位置config.mongoose.options为空config.mongoose.options显式声明功能影响当前可用当前可用行为更稳定改完记得重启eggjs 的配置改动不会热更新。如果你用了egg-mongoose的多数据源配置exports.mongoose.clients每个 client 的 options 都要加别只改默认那个。4. 验证请求链路从 MongoDB 连接到统一 Key 调用配置改完怎么确认真的生效分两层验证。第一层验证 MongoDB 连接第二层验证统一 Key 通道。第一层写个最简单的 controller 或直接在app.js启动钩子里打日志。eggjs 里可以这样确认 mongoose 已连接// app.js module.exports app { app.beforeStart(async () { const { mongoose } app; // 等待连接就绪 await mongoose.connection.readyState; app.logger.info(mongoose readyState:, mongoose.connection.readyState); }); };readyState为 1 表示已连接。启动项目看日志里有没有这行同时确认控制台不再出现 deprecated 警告。这一步过了说明useUnifiedTopology生效。第二层验证统一 Key 通道。写一个 service 方法用 Node 的fetchNode 18 内置或axios去调 TaoToken 的 API。以模型对话为例// app/service/ai.js const { Service } require(egg); class AiService extends Service { async chat(prompt) { const { baseURL, apiKey, model } this.app.config.taoToken; const res await fetch(${baseURL}/v1/chat/completions, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${apiKey}, }, body: JSON.stringify({ model, messages: [{ role: user, content: prompt }], }), }); if (!res.ok) { const text await res.text(); throw new Error(TaoToken request failed: ${res.status} ${text}); } return res.json(); } } module.exports AiService;调用一下// app/controller/home.js 里临时验证 const result await ctx.service.ai.chat(用一句话说明什么是 MongoDB 副本集); ctx.body result;成功的话你会拿到一个 JSON里面有choices数组第一项的message.content就是模型回复。这一步验证了三件事Base URL 可达、Key 有效、Model ID 正确。三件套缺一不可任何一项错都会报错下一节专门讲。如果你更习惯用现成的编码工具来验证Claude Code 的接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 里面有 Base URL、Key、Model ID 的填写位置说明。长期做编码和 Agent 任务的可以看 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 把统一通道用在日常开发流里。两层验证都过了说明你的 eggjs 项目既干净地连上了 MongoDB又能通过统一 Key 调外部能力。接下来把常见坑过一遍。5. 本篇常见报错排查401、local proxy failed、reading choices、OAuth改配置和验证过程中最容易撞上几类报错。逐个对照。401 Unauthorized。调 TaoToken API 时返回 401几乎都是 Key 的问题。检查三处Key 是否复制完整前后有没有多余空格、请求头是不是Authorization: Bearer key格式、Key 有没有被禁用或删除。如果你把 Key 写进了config.default.js但读的是环境变量确认环境变量真的注入了——process.env.TAOTOKEN_API_KEY为undefined时请求头会变成Bearer undefined服务端直接 401。local proxy failed。这个报错通常出现在你本地网络环境有额外代理设置时请求发不出去。检查你的 shell 或系统里有没有设置HTTP_PROXY、HTTPS_PROXY环境变量如果有且指向一个不可用的地址Node 的请求会走这个代理然后失败。临时清掉再试unset HTTP_PROXY unset HTTPS_PROXY然后重启 eggjs。注意这里说的是清理本地无效代理配置不是让你去搭什么通道纯粹是排除环境变量干扰。reading choices或Cannot read properties of undefined (reading choices)。这个报错说明你拿到的响应里没有choices字段但你代码里直接访问了result.choices[0]。原因通常是请求其实失败了返回的是错误 JSON比如{ error: {...} }你没检查res.ok就往下走。修法就是前面 service 里那样先判断res.ok不 OK 就把状态码和响应体打出来。另一个可能是 Model ID 写错服务端返回了非预期结构。OAuth 相关报错。如果你用 Claude Code 或类似工具接入遇到 OAuth 报错多半是认证方式选错了。这类工具支持 API Key 和 OAuth 两种模式用统一 Key 通道时应该选 API Key 模式填 Base URL Key Model ID 三件套。OAuth 模式走的是另一套流程混用会报错。接入文档里有明确说明照着填。再补一个 egg-mongoose 特有的坑配置改了但没生效。原因通常是config.default.js被config.local.js或config.prod.js覆盖了。eggjs 的配置加载顺序是 default → env → local后者覆盖前者。如果你在config.local.js里也写了mongoose配置它会盖掉 default 里的。检查一下各环境配置文件确保useUnifiedTopology在你实际运行的环境里存在。还有一个MongooseError: Operation buffering timed out。这跟 deprecated 警告不是一回事但常一起出现。它表示连接没建立成功操作被缓冲后超时。先确认 MongoDB 服务在跑、端口对、防火墙没拦。连接通了这个错自然消失。排查顺序建议先看控制台有没有 deprecated 警告配置问题再看 readyState连接问题最后看 API 返回状态码Key 和 Model 问题。一层层往下别跳。6. 把统一 Key 用在长期编码与 Agent 任务里MongoDB 那条警告处理完你的 eggjs 控制台应该干净了。但统一 Key 通道的价值不止于验证一次请求。当你项目里开始出现多个需要调模型的地方——代码补全、日志分析、自动化脚本、Agent 任务——每个地方各配一套 Key 会很快失控。把 Base URL、Key、Model ID 收敛到一处改一次全局生效这是长期维护省心的地方。日常编码场景Claude Code 的接入方式在文档里有完整步骤填好三件套就能用。需要跑 Agent 或长时间编码任务的Coding Plan 页面 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 有对应的方案说明。想先试试模型对话效果的模型对话页 https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 可以直接体验。Key 的管理和新建都在 API Keys 页 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 接入细节看文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。回到 eggjs 本身最后给你一个实用技巧把useUnifiedTopology这类连接选项抽成一个常量模块多环境复用避免每个 config 文件重复写、漏写。比如建config/mongoOptions.js// config/mongoOptions.js module.exports { useUnifiedTopology: true, useNewUrlParser: true, maxPoolSize: 10, };然后在各环境 config 里require进来。这样将来驱动升级要改选项只动一个文件。配置集中、凭证集中、验证路径清晰项目跑起来就少一类半夜被叫起来排查的意外。
返回列表