如何解决Firebase云函数调用Campaign Monitor API的ESOCKETTIMEDOUT错误
解决Firebase云函数中Campaign Monitor API的ESOCKETTIMEDOUT错误
我来帮你搞定这个ESOCKETTIMEDOUT的问题!虽然邮件能正常发送,但这个错误确实会干扰日志排查,而且背后其实是请求连接池或超时设置的问题,咱们一步步来解决:
核心原因
你遇到的这个超时错误,本质是批量请求时socket连接池资源不足,或者默认的超时时间太短,导致云函数里的HTTP请求在等待连接或响应时超时了。Campaign Monitor能收到请求,说明请求最终发出去了,但客户端这边因为等待超时触发了错误。
配置request选项的正确位置
你提到的agent: false和pool: {maxSockets: 100}是对的,关键是要把这些配置传给createsend-node底层用的request库。这个库允许在初始化API客户端时传入自定义的请求选项,具体做法如下:
1. 初始化API客户端时添加requestOptions
修改你的API初始化代码,加上自定义的请求配置:
const CreateSend = require('createsend-node'); // 初始化时传入requestOptions const api = new CreateSend({ apiKey: '你的Campaign Monitor API密钥', requestOptions: { agent: false, // 禁用默认Agent,避免连接复用超时 pool: { maxSockets: 100 }, // 增大连接池容量,适配批量请求 timeout: 30000, // 显式设置30秒超时(可根据需求调整) connectionTimeout: 15000 // 连接建立超时设置为15秒 } });
这些配置的作用:
agent: false:禁用Node.js默认的HTTP Agent,每个请求使用独立的socket连接,避免复用旧连接时的超时问题pool: {maxSockets:100}:把连接池的最大socket数从默认的5(或更低)调高,批量发邮件时不会因为连接数不够导致等待超时timeout和connectionTimeout:给请求足够的时间完成,避免因为Campaign Monitor的响应延迟触发客户端超时
2. 配合批量限流处理
除了调整请求配置,批量发邮件时最好做分批处理,避免一下子发起太多请求把socket资源耗尽。比如每次处理10个用户,间隔1秒再处理下一批:
async function sendBulkEmails(users) { const batchSize = 10; for (let i = 0; i < users.length; i += batchSize) { const currentBatch = users.slice(i, i + batchSize); // 并行处理当前批次的邮件请求 await Promise.all(currentBatch.map(user => { const emailDetails = { To: [{ Email: user.email, Name: user.name }], // 其他邮件配置... }; return new Promise((resolve, reject) => { api.transactional.sendSmartEmail(emailDetails, (err, res) => { if (err) { console.error(`给用户${user.email}发邮件失败:`, err); reject(err); } else { console.log(`已给用户${user.email}发送邮件`); resolve(res); } }); }); })); // 每批之间加个小延迟,避免请求过于密集 await new Promise(resolve => setTimeout(resolve, 1000)); } }
3. 调整云函数的超时设置
如果你的用户数量很多,批量处理可能需要超过默认的60秒超时,记得在firebase.json里延长云函数的超时时间:
{ "functions": { "runtimeOptions": { "timeoutSeconds": 540 // 最大支持540秒(9分钟),按需设置 } } }
验证效果
做完这些配置后,重新部署云函数,再测试批量发邮件的场景,应该就不会再出现ESOCKETTIMEDOUT错误了。如果还有问题,可以适当调高maxSockets或者超时时间,也可以检查Campaign Monitor的API速率限制,确保没有触发他们的限流规则。
内容的提问来源于stack exchange,提问作者Simon Kibsgård
相关产品推荐
相关产品推荐

