为何部署在AWS App Runner的.NET 6 API无法连接公开RDS PostgreSQL?
AWS App Runner部署.NET 6 API后RDS PostgreSQL连接超时排查方案
问题背景
我有一个面向移动应用的.NET 6 API,已完成Docker容器化,本地运行正常,数据库迁移可执行,也能通过pgAdmin正常操作RDS PostgreSQL实例。但部署到AWS App Runner后出现健康检查失败错误,日志显示连接RDS(地址52.215.162.0:5432)超时,导致数据库迁移失败。
相关代码(Program.cs)
public class Program { public static void Main(string[] args) { var host = CreateHostBuilder(args).Build(); using var scope = host.Services.CreateScope(); var services = scope.ServiceProvider; try { var context = services.GetRequiredService<DataContext>(); context.Database.Migrate(); } catch(Exception ex) { var logger = services.GetRequiredService<ILogger<Program>>(); logger.LogError(ex, "An error occured during migration"); } host.Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); }
完整错误日志
12-24-2022 09:10:17 PM Content root path: /app 12-24-2022 09:10:17 PM [40m[32minfo[39m[22m[49m: Microsoft.Hosting.Lifetime[0] 12-24-2022 09:10:17 PM Hosting environment: Production 12-24-2022 09:10:17 PM [40m[32minfo[39m[22m[49m: Microsoft.Hosting.Lifetime[0] 12-24-2022 09:10:17 PM Application started. Press Ctrl+C to shut down. 12-24-2022 09:10:17 PM [40m[32minfo[39m[22m[49m: Microsoft.Hosting.Lifetime[0] 12-24-2022 09:10:17 PM Now listening on: http://[::]:80 12-24-2022 09:10:17 PM [40m[32minfo[39m[22m[49m: Microsoft.Hosting.Lifetime[14] 12-24-2022 09:10:17 PM at API.Program.Main(String[] args) in /app/API/Program.cs:line 28 12-24-2022 09:10:17 PM at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.Migrate(DatabaseFacade databaseFacade) 12-24-2022 09:10:17 PM at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration) 12-24-2022 09:10:17 PM at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists() 12-24-2022 09:10:17 PM at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlDatabaseCreator.Exists() 12-24-2022 09:10:17 PM at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlDatabaseCreator.Exists(Boolean async, CancellationToken cancellationToken) 12-24-2022 09:10:17 PM at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlDatabaseCreator.Exists(Boolean async, CancellationToken cancellationToken) 12-24-2022 09:10:17 PM at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected) 12-24-2022 09:10:17 PM at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternal(Boolean errorsExpected) 12-24-2022 09:10:17 PM at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(Boolean errorsExpected) 12-24-2022 09:10:17 PM at Npgsql.NpgsqlConnection.Open() 12-24-2022 09:10:17 PM at Npgsql.NpgsqlConnection.<Open>g__OpenAsync|45_0(Boolean async, CancellationToken cancellationToken) 12-24-2022 09:10:17 PM at Npgsql.UnpooledConnectorSource.Get(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken) 12-24-2022 09:10:17 PM at Npgsql.Internal.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken) 12-24-2022 09:10:17 PM at Npgsql.Internal.NpgsqlConnector.<Open>g__OpenCore|195_1(NpgsqlConnector conn, SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken, Boolean isFirstAttempt) 12-24-2022 09:10:17 PM at Npgsql.Internal.NpgsqlConnector.RawOpen(SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken, Boolean isFirstAttempt) 12-24-2022 09:10:17 PM at Npgsql.Internal.NpgsqlConnector.Connect(NpgsqlTimeout timeout) 12-24-2022 09:10:17 PM at Npgsql.Internal.NpgsqlConnector.Connect(NpgsqlTimeout timeout) 12-24-2022 09:10:17 PM ---> System.TimeoutException: Timeout during connection attempt 12-24-2022 09:10:17 PM Npgsql.NpgsqlException (0x80004005): Failed to connect to 52.215.162.0:5432 12-24-2022 09:10:17 PM An error occured during migration 12-24-2022 09:10:17 PM [41m[30mfail[39m[22m[49m: API.Program[0] 12-24-2022 09:10:02 PM Entity Framework Core 6.0.12 initialized 'DataContext' using provider 'Npgsql.EntityFrameworkCore.PostgreSQL:6.0.8+e68dfe8b5cbe4a26d20acc36def6187aa1cfdda3' with options: None 12-24-2022 09:10:02 PM [40m[32minfo[39m[22m[49m: Microsoft.EntityFrameworkCore.Infrastructure[10403] 12-24-2022 09:09:39 PM Application is shutting down... 12-24-2022 09:09:39 PM [40m[32minfo[39m[22m[49m: Microsoft.Hosting.Lifetime[0] 12-24-2022 09:06:15 PM Content root path: /app 12-24-2022 09:06:15 PM [40m[32minfo[39m[22m[49m: Microsoft.Hosting.Lifetime[0] 12-24-2022 09:06:15 PM Hosting environment: Production 12-24-2022 09:06:15 PM [40m[32minfo[39m[22m[49m: Microsoft.Hosting.Lifetime[0] 12-24-2022 09:06:15 PM Application started. Press Ctrl+C to shut down. 12-24-2022 09:06:15 PM [40m[32minfo[39m[22m[49m: Microsoft.Hosting.Lifetime[0] 12-24-2022 09:06:15 PM Now listening on: http://[::]:80 12-24-2022 09:06:15 PM [40m[32minfo[39m[22m[49m: Microsoft.Hosting.Lifetime[14]
排查步骤
1. 检查RDS安全组入站规则
- 登录AWS控制台,找到目标RDS实例的安全组,确认入站规则是否允许App Runner访问5432端口:
- 若App Runner未配置VPC接入:在App Runner服务详情页的网络标签下获取出站IP范围,将这些IP段添加到RDS安全组的入站规则,协议选TCP,端口5432。
- 若App Runner配置了VPC接入:确保RDS安全组允许App Runner所在VPC的私有IP段访问,或者直接关联App Runner使用的安全组。
2. 验证App Runner的VPC配置(如果启用)
- 检查App Runner的VPC配置是否正确关联了RDS所在的VPC、子网和安全组。
- 确认子网的路由表包含指向RDS的路由,且子网的NACL规则未阻断5432端口的出站/入站流量。
3. 确认RDS实例的可访问性设置
- 若App Runner未用VPC,需确保RDS实例的公有可访问性设置为“是”,否则无法通过公网IP访问。
- 验证RDS实例的公网端点IP是否与日志中的52.215.162.0一致,避免端点配置错误。
4. 核对数据库连接字符串
- 检查App Runner环境变量中的连接字符串是否正确,包括用户名、密码、数据库名、端点,无拼写或格式错误。
- 本地使用相同的连接字符串测试连接(确保本地IP在RDS安全组允许列表),排除凭证或连接字符串本身的问题。
5. 调整健康检查参数
- 健康检查失败可能是因为启动时数据库迁移耗时过长,导致服务未就绪就被判定失败。可以在App Runner控制台修改健康检查的超时时间(建议设为30-60秒)和间隔时间,给迁移足够的执行时间。
- 若允许,可修改代码将迁移改为异步执行,或延迟健康检查的触发逻辑(需注意数据一致性风险)。
6. 检查App Runner网络出站限制
- 若使用自定义VPC,确认子网的NACL出站规则允许访问RDS的5432端口。
- 未使用VPC时,App Runner默认允许公网出站,但需确认是否有其他AWS服务(如WAF)限制了流量。
内容的提问来源于stack exchange,提问作者Ájfalusi Ábel
相关产品推荐
相关产品推荐

