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;
本文档描述了在2020年8月22日发布的nginx-module-postgres v1.0。
ngx_postgres是一个上游模块,允许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
配置保持活动参数:
max- 最大保持活动连接数(每个工作进程),mode- 后端匹配模式,overflow- 要么ignore保持活动连接池已满的事实并允许请求,但随后关闭连接,或者用503 Service Unavailable响应reject请求。
postgres_pass
- 语法:
postgres_pass upstream - 默认:
none - 上下文:
location,if location
设置将用于数据库连接的上游块的名称(可以包含变量)。
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仅适用于INSERT、UPDATE、DELETE、MOVE、FETCH和COPY SQL查询。
此指令可以在同一上下文中使用多次。
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
受INSERT、UPDATE、DELETE、MOVE、FETCH或COPY SQL查询影响的行数。
$postgres_query
PostgreSQL数据库看到的SQL查询。
示例配置
示例配置 #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 Web服务,返回带有适当HTTP状态代码的JSON响应。
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
在SQL查询中使用GET参数。
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
您还可以测试与以下模块的互操作性:
- ngx_coolkit,
- ngx_echo,
- ngx_form_input,
- ngx_set_misc,
- ngx_http_auth_request_module,
- nginx-eval-module (agentzh的分支),
- ngx_rds_json。
通过运行:
$ prove
另见
GitHub
您可以在nginx-module-postgres的GitHub 仓库中找到此模块的其他配置提示和文档。