基于.NET 6的AWS Lambda无法连接AWS RDS MySQL数据库
问题
本地通过Visual Studio的Mock Lambda Test Tool能正常连接AWS RDS MySQL并查询测试数据,但发布到AWS Lambda后,无论用Visual Studio发布测试还是AWS控制台测试都超时失败,日志显示30秒后超时(本地仅需3秒):
1/7/2023 11:27:33 PM START RequestId: 9b681991-11db-4b12-b771-a346ce5f8b5b Version: $LATEST 1/7/2023 11:28:03 PM 2023-01-08T07:28:03.814Z 9b681991-11db-4b12-b771-a346ce5f8b5b Task timed out after 30.03 seconds 1/7/2023 11:28:03 PM END RequestId: 9b681991-11db-4b12-b771-a346ce5f8b5b 1/7/2023 11:28:03 PM REPORT RequestId: 9b681991-11db-4b12-b771-a346ce5f8b5b Duration: 30033.62 ms Billed Duration: 30000 ms Memory Size: 256 MB Max Memory Used: 90 MB Init Duration: 277.23 ms
添加CloudWatch日志后发现,Lambda卡在conn.Open()调用处,推测是权限或VPC/安全组问题,但不知道怎么进一步排查。
已配置Lambda执行角色的对应权限,且Lambda与RDS共享同一VPC、子网和安全组,安全组也配置了出站规则(自认为足够Lambda发起连接)和入站规则。
测试代码在本地Mock工具运行正常:
try { // Connect to the database conn.Open(); await WriteCloudWatchLogEvent("Connected to dB", DateTime.UtcNow); cmd = new MySqlCommand(cmdString, conn); MySqlDataReader rdr = cmd.ExecuteReader(); var dataTable = new DataTable(); dataTable.Load(rdr); for (int i=0; i < dataTable.Rows.Count; i++) { ... do something ... } } catch (Exception ex) { await WriteCloudWatchLogEvent("Catch exception="+ex.ToString(), DateTime.UtcNow); } conn.Close();
排查步骤
1. 验证安全组入站规则
- 确认RDS的安全组入站规则是否允许Lambda所在安全组的流量访问MySQL端口(默认3306)。即使两者同属一个安全组,也需要明确配置入站规则,允许该安全组内的IP访问3306端口,而非仅依赖宽泛规则。
- 检查入站规则的来源是否为Lambda的安全组ID,而非特定IP(Lambda在VPC内的IP是动态的)。
2. 检查子网配置
- 确认Lambda部署的子网类型:如果是公有子网,可能无法直接访问部署在私有子网的RDS;如果是私有子网,需确认子网路由表包含指向VPC内其他子网的路由(目标为VPC CIDR,下一跳为本地),确保Lambda能路由到RDS所在子网。
- 若Lambda需要访问公网(比如拉取依赖),私有子网需配置NAT网关,但仅访问同VPC内的RDS时无需此配置。
3. 验证RDS的可访问性
- 在VPC内创建一个EC2实例,放在和Lambda相同的子网、安全组,用相同的连接字符串尝试连接RDS:
- 若EC2能连接,说明网络配置无问题,问题出在Lambda本身(比如角色权限、连接字符串配置);
- 若EC2也连接失败,说明网络/安全组配置存在问题,需继续排查。
4. 检查Lambda的网络权限与配置
- 确认Lambda执行角色拥有
ec2:CreateNetworkInterface、ec2:DescribeNetworkInterfaces、ec2:DeleteNetworkInterface权限——Lambda在VPC内运行需要这些权限创建弹性网络接口,缺失会导致网络连接失败。 - 确认Lambda的VPC配置包含了RDS所在的子网,或者至少包含能路由到RDS子网的子网。
5. 调试代码与连接配置
- 确认Lambda使用的连接字符串和本地一致,重点检查RDS端点、端口、用户名密码是否正确(避免本地用内网IP、Lambda用公网端点这类配置差异)。
- 将
conn.Open()改为异步调用await conn.OpenAsync(),同步调用在Lambda环境下可能引发线程阻塞,导致超时。 - 在
conn.Open()前添加日志输出连接字符串的关键信息(注意隐藏密码),验证配置准确性。
6. 检查RDS状态
- 确认RDS实例处于可用状态,无维护或故障;查看RDS日志,检查是否有拒绝连接的记录。
内容的提问来源于stack exchange,提问作者HiDefLoLife
相关产品推荐
相关产品推荐

