axios调用Go API访问MongoDB报连接池检出连接超时问题
问题描述
使用axios调用Go语言开发的API接口时触发如下报错:
timed out while checking out a connection from connection pool: context canceled; maxPoolSize: 10000, connections in use by cursors: 0, connections in use by transactions: 0, connections in use by other operations: 1
已做过的排查操作:
- 先后调整数据库连接池
maxPoolSize参数为100、200、10000,均无法解决问题 - 直接访问对应路由可以正常响应,仅axios发起调用时会触发上述错误
相关代码如下:
axios请求逻辑:
export async function validLogin(email, password) { const data = JSON.stringify({ email, password }); let headers = { 'Content-Type': 'application/json;charset=UTF-8', }; await axios.post('http://localhost:1323/profile/valid', data, headers) .then(response => { return response.data; }) .catch(err =>{ console.log(err); }); }
前端调用逻辑:
async function validateLogin() { if (password !== "" && email !== "") { const result = await validLogin(email, password) alert(result) if (result === "ok") setValidUser(true) } };
问题根因
几个核心问题共同导致报错:
- 前端axios传参错误:
axios.post的第三个参数要求是完整的请求配置对象,代码中直接传入headers对象,没有将headers包裹在配置的headers字段下,导致axios无法正确解析请求配置,发起的请求不符合预期,客户端提前中断请求后,Go端接收到的请求context被取消,此时数据库操作正在排队等待从连接池取连接,就抛出了context canceled的连接池超时错误。这也是直接访问接口正常、仅axios调用报错的原因——直接访问时请求不会被客户端异常中断,context不会提前取消,数据库操作能正常获取连接执行。 - 前端逻辑存在返回值丢失问题:
validLogin函数混用await和then写法,then回调中的return response.data只会返回给回调内部,不会作为validLogin函数的返回值,外层调用时拿到的result永远是undefined,就算请求成功也走不到setValidUser(true)的逻辑。 - 服务端配置不合理:盲目将
maxPoolSize调到10000完全没必要,常规业务场景下100以内的连接池大小足够支撑业务,过大的连接池配置反而会增加数据库负载,同时没有做好请求context和数据库操作的绑定,请求断开后不能及时取消排队的数据库操作,占用连接池资源。
修复方案
前端代码修复
调整axios请求逻辑,正确传参并修正返回值:
export async function validLogin(email, password) { // 不需要手动JSON.stringify,axios识别到json请求头会自动做序列化 const data = { email, password }; const config = { headers: { 'Content-Type': 'application/json;charset=UTF-8', } }; // 统一用try/catch处理异常,直接返回请求结果,避免返回值丢失 try { const response = await axios.post('http://localhost:1323/profile/valid', data, config) return response.data; } catch (err) { console.log(err); return null; } }
前端调用逻辑补充判空即可,原有逻辑不需要大改:
async function validateLogin() { if (password !== "" && email !== "") { const result = await validLogin(email, password) alert(result) if (result === "ok") { setValidUser(true) } } };
服务端优化
- 将数据库连接池
maxPoolSize调回合理值,根据业务并发量设置为10~100区间即可 - 给单次数据库操作设置合理的超时时间(建议2~5秒),避免无效排队占用连接资源
- 所有数据库操作必须绑定请求自带的context,请求中断时及时取消数据库操作,释放连接。
内容的提问来源于stack exchange,提问作者Elisa Souza
相关产品推荐
相关产品推荐

