AWS Lambda Node.js环境首次API调用循环插入MySQL失败问题求助
问题根因
- 你当前的Lambda Handler没有正确处理异步逻辑:
axios.get、数据库query、connection.end都是异步返回Promise的操作,你没有等待这些操作执行完成就返回响应,Lambda会直接冻结执行环境,未完成的操作会被终止- 首次调用是冷启动,数据库建连耗时更长,4条插入操作仅能完成1条就被冻结
- 第二次调用是热启动,执行环境已有缓存的数据库连接,插入操作执行速度更快,刚好能在冻结前全部完成
- 你没有将异步操作的Promise作为Handler的返回值返回,Lambda无法感知异步逻辑的执行状态,返回给API Gateway的响应为空,因此始终返回
{"message": "Internal server error"} - 用
forEach遍历执行异步插入操作不会等待所有异步任务完成,无论插入速度快慢都存在丢数据的风险 - 直接拼接SQL字符串存在SQL注入风险,生产环境必须禁用
修复方案
将Handler改为async/await写法,显式等待所有异步操作完成后再返回响应,改用参数化查询避免SQL注入。
修改后的完整代码如下:
'use strict'; const connection = require('serverless-mysql')({ config: { host: 'xxxxxx.xxxxx.ap-southeast-1.rds.amazonaws.com', user: 'xxx', password: 'xxx', database: 'xxx_db' } }) const axios = require('axios'); // 给handler加async关键字 exports.handler = async (event, context) => { // 避免Lambda等待空连接池超时,可选配置 context.callbackWaitsForEmptyEventLoop = false; try { // 等待API请求完成 const res = await axios.get('https://xxx.example/wp-json/wp/v2/posts'); const headerDate = res.headers?.date ?? 'no response date'; console.log('Status Code:', res.status); console.log('Date in Response header:', headerDate); const posts = res.data; // 用Promise.all等待所有插入操作完成 await Promise.all(posts.map(post => { // 改用参数化查询,避免SQL注入 const sql = `INSERT INTO tbl_post(news_id, title, excerpt, content, category, image_link, modified_date, show_in_banner_F, show_in_list_F) VALUES (?, ?, ?, ?, '', ?, now(), 0, 0)`; const params = [ post.id, post.title.rendered, post.excerpt.rendered, post.content.rendered, post.yoast_head_json.og_image[0].url ]; console.log(sql, params); return connection.query(sql, params); })); console.log("finished"); // 等待连接关闭完成 await connection.end(); const responseBody = { message: "OK" }; return { statusCode: 200, headers: { "Access-Control-Allow-Headers" : "Content-Type", "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "OPTIONS,POST,GET" }, body: JSON.stringify(responseBody) }; } catch (err) { console.log('Error: ', err.message); const responseBody = { message: "Fail" }; return { statusCode: 200, headers: { "Access-Control-Allow-Headers" : "Content-Type", "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "OPTIONS,POST,GET" }, body: JSON.stringify(responseBody) }; } }
内容的提问来源于stack exchange,提问作者alvinsusanto
相关产品推荐
相关产品推荐

