需求
项目需要在nginx的lua脚本中,访问nacos来获取redis的配置。记录一下过程。
ngx_lua模块中使用共享内存字典
在nginx
的conf.d
中增加一行,开启共享内存空间
lua_shared_dict DICT 1m;
然后是在lua中使用这个空间
-- 获取内存中的参数
local ip, ipFlags = ngx.shared.DICT:get(ipStr)
-- 设置参数值
success, err, forcible = ngx.shared.DICT:set(ipStr, ip)
ngx_lua中发送http请求
依赖lua-resty-http
库
local http = require "resty.http"
local httpc = http.new()
local url = "http://ip:端口/......"
local resStr --响应结果
local res, err = httpc:request_uri(url, {
method = "POST",
--args = str,
body = str,
headers = {
["Content-Type"] = "application/json",
}
})
if not res then
ngx.log(ngx.WARN,"failed to request: ", err)
return resStr
end
--请求之后,状态码
ngx.status = res.status
if ngx.status ~= 200 then
ngx.log(ngx.WARN,"非200状态,ngx.status:"..ngx.status)
return resStr
end
--响应的内容
resStr = res.body
解析返回值
从nacos中获取的返回值是这个样子的
spring:
redis:
database: 0
host: 1.1.1.1
password: 123
port: 6379
用正则来匹配
ip = string.match(resStr, "host:%s(.-)%c")
port = string.match(resStr, "port:%s(.+)")
passwd = string.match(resStr, "password:%s(.-)%c")
database = string.match(resStr, "database:%s(.-)%c")
这里port的正则跟别的不一样是因为它是最后一行了,他后面没有换行符
访问dns服务器获取ip
因为nacos
的地址每个环境也不一样,所以要用domain来进行访问,但是lua-resty-http
默认不支持对domain的解析,只能使用lua-resty-dns
来进行解析,再发送请求。
local resolver = require "resty.dns.resolver"
local http = require "resty.http"
function get_domain_ip_by_dns( domain )
-- 这里写死了google的域名服务ip,要根据实际情况做调整(例如放到指定配置或数据库中)
local dns = "8.8.8.8"
local r, err = resolver:new{
nameservers = {dns, {dns, 53} },
retrans = 5, -- 5 retransmissions on receive timeout
timeout = 2000, -- 2 sec
}
if not r then
return nil, "failed to instantiate the resolver: " .. err
end
local answers, err = r:query(domain)
if not answers then
return nil, "failed to query the DNS server: " .. err
end
if answers.errcode then
return nil, "server returned error code: " .. answers.errcode .. ": " .. answers.errstr
end
for i, ans in ipairs(answers) do
if ans.address then
return ans.address
end
end
return nil, "not founded"
end
-- 使用
local domain_ip, err = get_domain_ip_by_dns("nacos-0.nacos-headless.default.svc.cluster.local")
这里还有个需要注意的地方,在k8s的pods里直接 ping nacos-headless.default
是可用解析到的,但是在ngx_lua里却报 name error
,只有使用 nacos-0.nacos-headless.default.svc.cluster.local
才能正确获取到
nslookup nacos-headless.default 10.0.0.2
Server: 10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local
Name: nacos-headless.default
Address 1: 10.240.1.1 nacos-0.nacos-headless.default.svc.cluster.local
Address 2: 10.240.2.2 nacos-2.nacos-headless.default.svc.cluster.local
Address 3: 10.240.3.3 nacos-1.nacos-headless.default.svc.cluster.local
网友评论