Перейти к содержанию

postgres: Модуль PostgreSQL для NGINX

Установка

Вы можете установить этот модуль в любой дистрибутив на базе RHEL, включая, но не ограничиваясь:

  • RedHat Enterprise Linux 7, 8, 9 и 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 и Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-postgres
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-postgres

Активируйте модуль, добавив следующее в начало файла /etc/nginx/nginx.conf:

load_module modules/ngx_postgres_module.so;

Этот документ описывает nginx-module-postgres v1.0, выпущенный 22 августа 2020 года.


ngx_postgres — это модуль upstream, который позволяет nginx напрямую взаимодействовать с базой данных PostgreSQL.

Ответ генерируется в формате rds, поэтому он совместим с модулями ngx_rds_json и ngx_drizzle.

Директивы конфигурации

postgres_server

  • синтаксис: postgres_server ip[:port] dbname=dbname user=user password=pass
  • по умолчанию: none
  • контекст: upstream

Установите данные о сервере базы данных.

postgres_keepalive

  • синтаксис: postgres_keepalive off | max=count [mode=single|multi] [overflow=ignore|reject]
  • по умолчанию: max=10 mode=single overflow=ignore
  • контекст: upstream

Настройте параметры keepalive:

  • max - максимальное количество соединений keepalive (на процесс-воркер),
  • mode - режим сопоставления бэкенда,
  • overflow - либо ignore факт того, что пул соединений keepalive полон и разрешить запрос, но закрыть соединение после этого, либо reject запрос с ответом 503 Service Unavailable.

postgres_pass

  • синтаксис: postgres_pass upstream
  • по умолчанию: none
  • контекст: location, if location

Установите имя блока upstream, который будет использоваться для соединений с базой данных (может включать переменные).

postgres_query

  • синтаксис: postgres_query [methods] query
  • по умолчанию: none
  • контекст: http, server, location, if location

Установите строку запроса (может включать переменные). Когда указаны методы, запрос используется только для них, в противном случае он используется для всех методов.

Эта директива может использоваться более одного раза в одном контексте.

postgres_rewrite

  • синтаксис: postgres_rewrite [methods] condition [=]status_code
  • по умолчанию: none
  • контекст: http, server, location, if location

Перезапишите код ответа status_code, когда заданное условие выполнено (первое условие выигрывает!):

  • no_changes - ни одна строка не была затронута запросом,
  • changes - по крайней мере, одна строка была затронута запросом,
  • no_rows - ни одна строка не была возвращена в результирующем наборе,
  • rows - по крайней мере, одна строка была возвращена в результирующем наборе.

Когда status_code предваряется знаком =, оригинальное тело ответа отправляется клиенту вместо стандартной страницы ошибки для данного status_code.

По замыслу, как no_changes, так и changes применяются только к SQL-запросам INSERT, UPDATE, DELETE, MOVE, FETCH и COPY.

Эта директива может использоваться более одного раза в одном контексте.

postgres_output

  • синтаксис: postgres_output rds|text|value|binary_value|none
  • по умолчанию: rds
  • контекст: http, server, location, if location

Установите формат вывода:

  • rds - вернуть все значения из результирующего набора в формате rds (с соответствующим Content-Type),
  • text - вернуть все значения из результирующего набора в текстовом формате (с дефолтным Content-Type), значения разделены новой строкой,
  • value - вернуть одно значение из результирующего набора в текстовом формате (с дефолтным Content-Type),
  • binary_value - вернуть одно значение из результирующего набора в двоичном формате (с дефолтным Content-Type),
  • none - ничего не возвращать, это следует использовать только при извлечении значений с помощью postgres_set для использования с другими модулями (без Content-Type).

postgres_set

  • синтаксис: postgres_set $variable row column [optional|required]
  • по умолчанию: none
  • контекст: http, server, location

Получите одно значение из результирующего набора и сохраните его в $variable.

Когда уровень требования установлен на required, и значение либо вне диапазона, NULL или нулевой длины, тогда nginx возвращает ответ 500 Internal Server Error. Такое условие тихо игнорируется, когда уровень требования установлен на optional (по умолчанию).

Номера строк и столбцов начинаются с 0. Имя столбца может использоваться вместо номера столбца.

Эта директива может использоваться более одного раза в одном контексте.

postgres_escape

  • синтаксис: postgres_escape $escaped [[=]$unescaped]
  • по умолчанию: none
  • контекст: http, server, location

Экранируйте и заключите в кавычки строку $unescaped. Результат сохраняется в переменной $escaped, которую можно безопасно использовать в SQL-запросах.

Поскольку nginx не может отличить пустые строки от несуществующих строк, все пустые строки по умолчанию экранируются в значение NULL. Это поведение можно отключить, предварив строку $unescaped знаком =.

postgres_connect_timeout

  • синтаксис: postgres_connect_timeout timeout
  • по умолчанию: 10s
  • контекст: http, server, location

Установите тайм-аут для подключения к базе данных.

postgres_result_timeout

  • синтаксис: postgres_result_timeout timeout
  • по умолчанию: 30s
  • контекст: http, server, location

Установите тайм-аут для получения результата из базы данных.

Переменные конфигурации

$postgres_columns

Количество столбцов в полученном результирующем наборе.

$postgres_rows

Количество строк в полученном результирующем наборе.

$postgres_affected

Количество строк, затронутых SQL-запросами INSERT, UPDATE, DELETE, MOVE, FETCH или COPY.

$postgres_query

SQL-запрос, как его видит база данных PostgreSQL.

Примеры конфигураций

Пример конфигурации #1

Вернуть содержимое таблицы cats (в формате rds).

http {
    upstream database {
        postgres_server  127.0.0.1 dbname=test
                         user=test password=test;
    }

    server {
        location / {
            postgres_pass   database;
            postgres_query  "SELECT * FROM cats";
        }
    }
}

Пример конфигурации #2

Вернуть только те строки из таблицы sites, которые соответствуют фильтру host, который оценивается для каждого запроса на основе переменной $http_host.

http {
    upstream database {
        postgres_server  127.0.0.1 dbname=test
                         user=test password=test;
    }

    server {
        location / {
            postgres_pass   database;
            postgres_query  SELECT * FROM sites WHERE host='$http_host'";
        }
    }
}

Пример конфигурации #3

Передать запрос на бэкенд, выбранный из базы данных (маршрутизатор трафика).

http {
    upstream database {
        postgres_server  127.0.0.1 dbname=test
                         user=test password=test;
    }

    server {
        location / {
            eval_subrequest_in_memory  off;

            eval $backend {
                postgres_pass    database;
                postgres_query   "SELECT * FROM backends LIMIT 1";
                postgres_output  value 0 0;
            }

            proxy_pass  $backend;
        }
    }
}

Требуемые модули (кроме ngx_postgres):

Пример конфигурации #4

Ограничить доступ к локальным файлам, аутентифицируясь через базу данных PostgreSQL.

http {
    upstream database {
        postgres_server  127.0.0.1 dbname=test
                         user=test password=test;
    }

    server {
        location = /auth {
            internal;

            postgres_escape   $user $remote_user;
            postgres_escape   $pass $remote_passwd;

            postgres_pass     database;
            postgres_query    "SELECT login FROM users WHERE login=$user AND pass=$pass";
            postgres_rewrite  no_rows 403;
            postgres_output   none;
        }

        location / {
            auth_request      /auth;
            root              /files;
        }
    }
}

Требуемые модули (кроме ngx_postgres):

Пример конфигурации #5

Простой RESTful веб-сервис, возвращающий JSON-ответы с соответствующими HTTP статус-кодами.

http {
    upstream database {
        postgres_server  127.0.0.1 dbname=test
                         user=test password=test;
    }

    server {
        set $random  123;

        location = /numbers/ {
            postgres_pass     database;
            rds_json          on;

            postgres_query    HEAD GET  "SELECT * FROM numbers";

            postgres_query    POST      "INSERT INTO numbers VALUES('$random') RETURNING *";
            postgres_rewrite  POST      changes 201;

            postgres_query    DELETE    "DELETE FROM numbers";
            postgres_rewrite  DELETE    no_changes 204;
            postgres_rewrite  DELETE    changes 204;
        }

        location ~ /numbers/(?<num>\d+) {
            postgres_pass     database;
            rds_json          on;

            postgres_query    HEAD GET  "SELECT * FROM numbers WHERE number='$num'";
            postgres_rewrite  HEAD GET  no_rows 410;

            postgres_query    PUT       "UPDATE numbers SET number='$num' WHERE number='$num' RETURNING *";
            postgres_rewrite  PUT       no_changes 410;

            postgres_query    DELETE    "DELETE FROM numbers WHERE number='$num'";
            postgres_rewrite  DELETE    no_changes 410;
            postgres_rewrite  DELETE    changes 204;
        }
    }
}

Требуемые модули (кроме ngx_postgres):

Пример конфигурации #6

Используйте параметр GET в SQL-запросе.

location /quotes {
    set_unescape_uri  $txt $arg_txt;
    postgres_escape   $txt;
    postgres_pass     database;
    postgres_query    "SELECT * FROM quotes WHERE quote=$txt";
}

Требуемые модули (кроме ngx_postgres):

Тестирование

ngx_postgres поставляется с полным набором тестов на основе Test::Nginx.

Вы можете протестировать основную функциональность, запустив:

$ TEST_NGINX_IGNORE_MISSING_DIRECTIVES=1 prove

Вы также можете протестировать совместимость с следующими модулями:

запустив:

$ prove

См. также

GitHub

Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-postgres.