Postgresql:无法建立连接,因为目标机器主动拒绝

Postgresql: No connection could be made because the target machine actively refused it

运行 Azurewindows 服务器 2012 R2 上的 Postgresql 9.5

虽然 运行 对我的应用程序进行了一些负载测试,但我收到无法连接到 postgres 服务器的错误。在 postgres 的日志中,我收到以下消息:

could not receive data from client: No connection could be made because the target machine actively refused it.

这只会在负载测试进入下一个场景时发生,命中代码的不同部分。因此需要新的数据库连接。但在 10-20 秒后,场景的其余部分可以完美运行,不会遇到任何其他问题。所以问题似乎是 tcp 连接。 (我的代码重试了几次,但让它重试20秒是不可行的)

我在配置文件中使用以下设置

postgresql.conf

listen_addresses = '*'
max_connections = 500   
shared_buffers = 1024MB     
temp_buffers = 2MB
work_mem = 2MB  
maintenance_work_mem = 128MB        

pg_hba.conf

host    all             all             0.0.0.0/0               trust
host    all             all             ::/0                    trust

我知道,我知道..接受每个人的连接并不能节省,但这只是为了测试目的,并确保这些设置不会阻止任何连接。 So this answer is void

我一直在监视服务器上的连接数,在负载下它稳定在 75。Postgres 使用大约 350mb 的 RAM。因此,鉴于配置和虚拟机规格(7gb ram),应该有足够的 space 来创建更多连接。但是,当下一个场景启动时,连接数不会增加,它会保持水平并开始提供有关无法建立连接的日志消息。

这可能是什么问题?

最可能的原因是 Firewall/Anti-virus:

  • Software/Personal 防火墙设置
  • 多个Software/Personal防火墙
  • 杀毒软件
  • LSP 层
  • (虚拟)路由器固件

您当前的 Azure 基础架构是否包含防火墙或防病毒软件?

此外,在进行一些额外的搜索时,它看起来像是一个标准的 Windows "connection refused" 消息,这表明 PostgreSQL 正在尝试连接到某个东西但被拒绝了。

您网络中的一个网络元素也可能 - 假设您仍然连接到服务器 - 将延迟或丢弃一些 DB login/authentication 网络数据包(例如被认为是假的 auth.replay ) ...

出现错误时,您也可以使用数据包分析器(如Wireshark)来record/inspect网络流量。

此致

听起来这并不是真正的 Postgres 问题(因此您正在检查的数据库统计信息没有变化),而是流量被服务器停止了。可能是因为在处理您的负载测试查询时该端口上的流量已饱和?

如果这适用于您的设置,听起来您并没有达到 Azure resource limits (including the database limits 中的任何一个?),但是如果没有关于您的负载测试的更多详细信息,很难准确地说出需要什么。

网络上的解决方案和其他 SO 答案建议:

  • 禁用 TCP 自动调整并调整服务器上的 TCP/IP 注册表项,例如设置 TcpAckFrequency - 有关详细信息,请参阅 this article
  • 调整 TCP 设置(如 WinsockListenBacklog) - which may be affected by whether connection pooling is in use or not - see this MS support article,它适用于 SQL Server 2005,但有一些关于排除被拒绝 TCP/IP 连接的重要提示(使用网络监视器,但适用于较新的工具)
  • 如果您对服务器有足够的控制权,请求处理速度会更快 - source
  • 禁用网络代理(在您的负载测试应用程序中):<defaultProxy> <proxy usesystemdefault="False"/> </defaultProxy> -

当我尝试从我的应用程序连接 Postgresql 时,我在我的 AspNet 核心应用程序中遇到了同样的问题。当我调用 Migrate 函数时,错误在 Program.cs 文件中抛出。

public static void Main(string[] args) {
    try {
        var host = BuildWebHost(args);
        using(var scope = host.Services.CreateScope()) {
            // Migrate once after app is started.
            scope.ServiceProvider.GetService <MyDatabaseContext>().Migrate();
        }
        host.Run();
    }
    catch(Exception e) {
        //NLog: catch setup errors
        _logger ? .Error(e, "Stopped program because of exception: ");
        throw;
    }
}

为了解决这个问题,我执行了以下步骤。

  1. 通过转到 services.msc
  2. 检查 Postgresql 服务是否 运行
  3. 尝试使用我在数据库上下文中提供的用户名和密码登录 pgAdmin

一切都是文件,正如你所知 5432Postgresql 的默认端口,不知何故我在我的应用程序连接字符串中使用了不同的端口,改变它到 5432 为我解决了这个问题。

"ConnectionString": "User Id=postgres;Password=mypwd;Host=localhost;Port=5432;Database=mydb;"

我在尝试攻击我的 api 时遇到了类似的问题,我看到了 Npgsql.NpgsqlException No connection could be made because the target machine actively refused it.

然而,我的问题归结为这样一个事实,即我 re-creating 我的每个查询 NpgsqlConnection 而不是 re-using 并保持它的活力。