Nginx lua openresty 变量作用域
Nginx lua openresty variable scope
这里是 openresty nginx.conf 文件的工作示例。在这个例子中,我多次请求 redis。如您所见,我首先从 redis 请求数据以检查域是否可以获取 SSL,然后再次获取代理请求的后端,然后我添加了 S3 代理,我将需要再次从 redis 请求数据。我是 OpenResty 和 Lua 的新手,我想知道是否可以从 redis 获取一次数据并在脚本中多次使用它?
user www-data;
worker_processes auto;
pid /run/openresty.pid;
events {
worker_connections 1024;
}
error_log /var/log/openresty/error.log debug;
http {
resolver 127.0.0.53 ipv6=off;
lua_shared_dict acme 16m;
init_by_lua_block {
require("resty.acme.autossl").init({
tos_accepted = true,
staging = true,
account_key_path = "/etc/openresty/account.key",
account_email = "didnt@forgot.removing",
domain_whitelist_callback = function(domain)
local redis = require "resty.redis"
local rds = redis:new()
local ok, err = rds:connect("127.0.0.1", 6379)
if not ok then
ngx.log(ngx.ERR, "failed to connect to redis: ", err)
return ngx.exit(500)
end
local res, err = rds:exists(domain)
if res == 1 then
return true
end
if res == 0 then
return false
end
end
})
}
init_worker_by_lua_block {
require("resty.acme.autossl").init_worker()
}
server {
access_log /var/log/openresty/access.log;
listen 80;
listen 443 ssl;
server_name _;
location / {
set $backend '';
set $tenant '';
access_by_lua '
local domain = ngx.req.get_headers()["Host"]
local key = "site:" .. domain
if not domain then
ngx.log(ngx.ERR, "message 404 missing")
return ngx.exit(404)
end
local redis = require "resty.redis"
local rds = redis:new()
local ok, err = rds:connect("127.0.0.1", 6379)
if not ok then
ngx.log(ngx.ERR, "failed to connect to redis: ", err)
return ngx.exit(500)
end
local all, err = rds:hgetall(key)
if not all then
ngx.log(ngx.ERR, "no komprende: ", err)
return ngx.exit(505)
end
if all == ngx.null then
ngx.log(ngx.ERR, "no host found for key ", key)
return ngx.exit(404)
end
local result = {}
for i = 1, #all, 2 do
result[all[i]] = all[i+1]
end
ngx.var.backend = result["backend"]
ngx.var.tenant = result["tenantID"]
ngx.log(ngx.ERR, "uhm: ", ngx.var.backend)
';
add_header X-TenantID $tenant always;
proxy_pass http://$backend;
}
location ~* ^/static/(.*) {
resolver 127.0.0.53 valid=300s;
resolver_timeout 10s;
set $s3_bucket 'drasha.ams3.digitaloceanspaces.com';
set $url_full '';
proxy_http_version 1.1;
proxy_set_header Host $s3_bucket;
proxy_set_header Authorization '';
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header Set-Cookie;
proxy_ignore_headers "Set-Cookie";
proxy_buffering off;
proxy_intercept_errors on;
proxy_pass http://$s3_bucket/AYAYA/$url_full;
}
lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
lua_ssl_verify_depth 2;
ssl_certificate /etc/openresty/default.pem;
ssl_certificate_key /etc/openresty/default.key;
ssl_certificate_by_lua_block {
require("resty.acme.autossl").ssl_certificate()
}
location /.well-known {
content_by_lua_block {
require("resty.acme.autossl").serve_http_challenge()
}
}
}
}
OpenResty 运行 Lua hooks in a sandbox,所以不能使用全局变量共享数据。
你应该使用 Data Sharing within an Nginx Worker
通常的做法是在 Lua 模块级别缓存任何内容,如果存储在 Redis 中的数据可能会更改,则可能有一些合理的有效期。
顺便说一句 - 不要使用 XXX_by_lua 指令 - 你应该注意 nginx 转义规则,使用 XXX_by_lua_block.
附加示例:
local redis = require"resty-redis"
-- the module
local _M = {}
local hgetall_results = {}
_M.hgetall = function(key)
if hgetall_results[key] then
return hgetall_results[key]
end
local rds = redis:new()
local ok, err = rds:connect("127.0.0.1", 6379)
local all, err = rds:hgetall(key)
local result = {}
for i = 1, #all, 2 do
result[all[i]] = all[i+1]
end
-- cache
hgetall_results[key] = result
return result
end
return _M
上面的例子只是说明了通常的模块范围缓存模式。
错误处理自行解决。
这里是 openresty nginx.conf 文件的工作示例。在这个例子中,我多次请求 redis。如您所见,我首先从 redis 请求数据以检查域是否可以获取 SSL,然后再次获取代理请求的后端,然后我添加了 S3 代理,我将需要再次从 redis 请求数据。我是 OpenResty 和 Lua 的新手,我想知道是否可以从 redis 获取一次数据并在脚本中多次使用它?
user www-data;
worker_processes auto;
pid /run/openresty.pid;
events {
worker_connections 1024;
}
error_log /var/log/openresty/error.log debug;
http {
resolver 127.0.0.53 ipv6=off;
lua_shared_dict acme 16m;
init_by_lua_block {
require("resty.acme.autossl").init({
tos_accepted = true,
staging = true,
account_key_path = "/etc/openresty/account.key",
account_email = "didnt@forgot.removing",
domain_whitelist_callback = function(domain)
local redis = require "resty.redis"
local rds = redis:new()
local ok, err = rds:connect("127.0.0.1", 6379)
if not ok then
ngx.log(ngx.ERR, "failed to connect to redis: ", err)
return ngx.exit(500)
end
local res, err = rds:exists(domain)
if res == 1 then
return true
end
if res == 0 then
return false
end
end
})
}
init_worker_by_lua_block {
require("resty.acme.autossl").init_worker()
}
server {
access_log /var/log/openresty/access.log;
listen 80;
listen 443 ssl;
server_name _;
location / {
set $backend '';
set $tenant '';
access_by_lua '
local domain = ngx.req.get_headers()["Host"]
local key = "site:" .. domain
if not domain then
ngx.log(ngx.ERR, "message 404 missing")
return ngx.exit(404)
end
local redis = require "resty.redis"
local rds = redis:new()
local ok, err = rds:connect("127.0.0.1", 6379)
if not ok then
ngx.log(ngx.ERR, "failed to connect to redis: ", err)
return ngx.exit(500)
end
local all, err = rds:hgetall(key)
if not all then
ngx.log(ngx.ERR, "no komprende: ", err)
return ngx.exit(505)
end
if all == ngx.null then
ngx.log(ngx.ERR, "no host found for key ", key)
return ngx.exit(404)
end
local result = {}
for i = 1, #all, 2 do
result[all[i]] = all[i+1]
end
ngx.var.backend = result["backend"]
ngx.var.tenant = result["tenantID"]
ngx.log(ngx.ERR, "uhm: ", ngx.var.backend)
';
add_header X-TenantID $tenant always;
proxy_pass http://$backend;
}
location ~* ^/static/(.*) {
resolver 127.0.0.53 valid=300s;
resolver_timeout 10s;
set $s3_bucket 'drasha.ams3.digitaloceanspaces.com';
set $url_full '';
proxy_http_version 1.1;
proxy_set_header Host $s3_bucket;
proxy_set_header Authorization '';
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header Set-Cookie;
proxy_ignore_headers "Set-Cookie";
proxy_buffering off;
proxy_intercept_errors on;
proxy_pass http://$s3_bucket/AYAYA/$url_full;
}
lua_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
lua_ssl_verify_depth 2;
ssl_certificate /etc/openresty/default.pem;
ssl_certificate_key /etc/openresty/default.key;
ssl_certificate_by_lua_block {
require("resty.acme.autossl").ssl_certificate()
}
location /.well-known {
content_by_lua_block {
require("resty.acme.autossl").serve_http_challenge()
}
}
}
}
OpenResty 运行 Lua hooks in a sandbox,所以不能使用全局变量共享数据。
你应该使用 Data Sharing within an Nginx Worker 通常的做法是在 Lua 模块级别缓存任何内容,如果存储在 Redis 中的数据可能会更改,则可能有一些合理的有效期。
顺便说一句 - 不要使用 XXX_by_lua 指令 - 你应该注意 nginx 转义规则,使用 XXX_by_lua_block.
附加示例:
local redis = require"resty-redis"
-- the module
local _M = {}
local hgetall_results = {}
_M.hgetall = function(key)
if hgetall_results[key] then
return hgetall_results[key]
end
local rds = redis:new()
local ok, err = rds:connect("127.0.0.1", 6379)
local all, err = rds:hgetall(key)
local result = {}
for i = 1, #all, 2 do
result[all[i]] = all[i+1]
end
-- cache
hgetall_results[key] = result
return result
end
return _M
上面的例子只是说明了通常的模块范围缓存模式。 错误处理自行解决。