pgbouncer - не удалось подключиться к серверу: адрес уже используется (0x00002740 / 10048) - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть приложение, использующее libpq для подключения к postgresql серверу и использующее pgbouncer в качестве пула соединений

    if (pconn == nullptr) {
        pconn = PQconnectdb(chrConnectStr);
    }
    if (PQstatus(pconn) == CONNECTION_BAD) {

        //If it fails, try to connect once
        pconn = PQconnectdb(chrConnectStr);
        //Make an error if it still fails
        if (PQstatus(pconn) == CONNECTION_BAD) {  
            //Error sometimes occurred here when test with concurrent connection
            return S_FALSE;
        }
    }
    ....... 
    //When connection OK, doing SQL execution
    //Close connection after finish
    PQFinish(pconn);

Все хорошо, когда я запускаю один экземпляр приложения. Но когда я тестирую с несколькими экземплярами одновременно (около 5 экземпляров), иногда я получаю CONNECTION_BAD status

В то время я проверял PQerrorMessage(conn) и вижу сообщение об ошибке:

could not connect to server: Address already in use (0x00002740/10048)
    Is the server running on host "localhost" (127.0.0.1) and accepting
    TCP/IP connections on port 6543?

Вот конфигурация pgbouncer

[databases]
food = host=127.0.0.1 dbname=MyDB auth_user=MyUser

[pgbouncer]
listen_port = 6543
listen_addr = *
auth_type = md5
auth_file = D:\PostgreSQL\pgbouncer\users.txt
admin_users = MyUser
syslog = 1
default_pool_size = 100
server_reset_query = DEALLOCATE ALL

Также в настройках postgres.conf I: max_connections = 500

1 Ответ

0 голосов
/ 11 февраля 2020

С man 2 bind:

EADDRINUSE
(целые rnet доменные сокеты) Номер порта был указан как ноль в структуре адреса сокета, но при попытке связать для эфемерного порта было определено, что все номера портов в диапазоне эфемерных портов в настоящее время используются. См. Обсуждение /proc/sys/net/ipv4/ip_local_port_range ip(7).

И из man 7 ip:

/proc интерфейсов
Протокол IP поддерживает набор /proc интерфейсы для настройки некоторых глобальных параметров. Доступ к параметрам можно получить путем чтения или записи файлов в каталоге /proc/sys/net/ipv4/. Интерфейсы, описанные как Boolean, принимают целочисленное значение с ненулевым значением («true»), означающим, что соответствующая опция включена, и нулевым значением («false»), означающим, что параметр отключен.

[. ..]

ip_local_port_range (начиная с Linux 2.2)
Этот файл содержит два целых числа, которые определяют диапазон локального порта по умолчанию, назначенный сокетам, которые явно не связаны с номером порта, то есть диапазон, используемый для эфемерных портов. Эфемерный порт назначается сокету в следующих случаях:

  • номер порта в адресе сокета указывается как 0 при вызове bind(2);

  • listen(2) вызывается для сокета потока, который ранее не был связан;

  • connect(2) был вызван для сокета, который ранее не был связан;

  • sendto(2) вызывается на сокете дейтаграммы, который ранее не был связан.

    Распределение эфемерных портов начинается с первого номера в ip_local_port_range и заканчивается вторым номером. Если диапазон временных портов исчерпан, соответствующий системный вызов возвращает ошибку (но см. BUGS).

    Обратите внимание, что диапазон портов в ip_local_port_range не должен конфликтовать с портами, используемыми для маскировки (хотя дело обрабатывается). Кроме того, произвольный выбор может вызвать проблемы с некоторыми фильтрами пакетов брандмауэра, которые делают предположения об используемых локальных портах. Первое число должно быть, по крайней мере, больше 1024, или лучше, больше, чем 4096, чтобы избежать конфликтов с хорошо известными портами и минимизировать проблемы с брандмауэром.

Похоже на меня у вас заканчиваются эфемерные порты. У тебя так много связей? Возможно, поможет увеличение диапазона эфемерных портов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...