无法从在GCP Cloud Run上运行的.net应用连接到Postgres实例

时间:2020-08-26 14:21:37

标签: c# google-cloud-platform entity-framework-core npgsql google-cloud-run

我有一个在GCP云运行实例中运行的应用程序,它使用映射到pgsql数据库上的EF Core,但由于某种原因我无法连接到数据库

这是用于连接数据库的代码:

Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<postgresContext>(options =>
        options.UseNpgsql(SecretManagerAccessor.GetConnectionString())
    );
}

控制器:

public MyController(IConfiguration configuration, postgresContext context, IMapper mapper)
{
    _configuration = configuration;
    _context = context;
    _mapper = mapper;
}

[HttpPost]
public IActionResult Post([FromBody] Body body)
{
    try
    {
        var repo = new SourceRepository(_context);
        var sources = repo.GetAll();
        foreach (var source in sources)
        {
            Console.WriteLine($"{source.SrcId} : {source.SrcInfo}");
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
    }
    
    return Ok();
}

最后是SourceRepository:

private readonly postgresContext _db;
private readonly DbSet<Source> _source;

public SourceRepository(postgresContext db)
{
    _db = db;
    _source = db.Set<Source>();
}

public IEnumerable<Source> GetAll()
{
    return _source;
}

我尝试了两种类型的连接字符串:

Server=xx.xx.xxx.xx;Port=5432;Database=MyDb;Username=username;Password=pass using this website

Host=xx.xx.xxx.xx;Database=MyDb;Username=username;Password=pass using this documentation

这些字符串托管在GCP的Secret Manager中,我使用“数据库优先”方法生成了存储对象和上下文。 Cloud Run服务帐户具有“ Cloud SQL Admin”权限(即使它应与客户端级别一起使用)。

我得到的错误是:

A 2020-08-26T13:58:49.877242Z An error occurred using the connection to database 'MyDb' on server 'tcp://xx.xx.xxx.xxx:5432'. 
A 2020-08-26T13:58:49.877242Z System.InvalidOperationException: An exception has been raised that is likely due to a transient failure. 
A 2020-08-26T13:58:49.877286Z  ---> Npgsql.NpgsqlException (0x80004005): Exception while connecting 
A 2020-08-26T13:58:49.877295Z  ---> System.TimeoutException: Timeout during connection attempt 
A 2020-08-26T13:58:49.877485Z    at Npgsql.NpgsqlConnector.Connect(NpgsqlTimeout timeout) 
A 2020-08-26T13:58:49.877514Z    at Npgsql.NpgsqlConnector.Connect(NpgsqlTimeout timeout) 
A 2020-08-26T13:58:49.877528Z    at Npgsql.NpgsqlConnector.RawOpen(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken) 
A 2020-08-26T13:58:49.877540Z    at Npgsql.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken) 
A 2020-08-26T13:58:49.877553Z    at Npgsql.ConnectorPool.AllocateLong(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken) 
A 2020-08-26T13:58:49.878103Z    at Npgsql.NpgsqlConnection.<>c__DisplayClass32_0.<<Open>g__OpenLong|0>d.MoveNext() 
A 2020-08-26T13:58:49.878128Z --- End of stack trace from previous location where exception was thrown --- 
A 2020-08-26T13:58:49.878136Z    at Npgsql.NpgsqlConnection.Open() 
A 2020-08-26T13:58:49.878145Z    at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(Boolean errorsExpected) 
A 2020-08-26T13:58:49.878152Z    at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected) 
A 2020-08-26T13:58:49.878161Z    at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject) 
A 2020-08-26T13:58:49.878170Z    at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.InitializeReader(DbContext _, Boolean result) 
A 2020-08-26T13:58:49.878180Z    at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded) 
A 2020-08-26T13:58:49.878188Z    --- End of inner exception stack trace --- 
A 2020-08-26T13:58:49.878197Z    at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded) 
A 2020-08-26T13:58:49.878203Z    at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext() 
A 2020-08-26T13:58:49.878211Z    at MyProject.Controllers.MyController.Post(Body body) in /app/Controllers/MyController.cs:line 62 

我通过使用以下代码简化了测试,但是仍然存在相同的问题:

        //GET : api/MyController
[HttpGet]
public IActionResult Get()
{
    Console.WriteLine("Get route called");
    try
    {
        _context.Database.CanConnect();
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
    }

    return Ok();
}

1 个答案:

答案 0 :(得分:1)

创建实例时,可以使用标志--add-cloudsql-instances。 Cloud Run将为您激活并配置Cloud SQL代理。

连接字符串应类似于此字符串 "Server=/cloudsql/your-project-id:us-central1:instance-name;Uid=aspnetuser;Pwd=;Database=votes"

您可以看看documentation

还有一个仓库显示如何使用Postgres repo在Cloud Run上构建C#应用程序