为什么我们的域名不能被解析
比如在使用 MySQL 实例时某些云会给一个私有的域名搭配自有的 使用。
以上代码在直接使用时往往会报一个无法解析的错误。那么怎么在 OpenResty 中使用域名呢?
我们可以直接在 Nginx 的配置文件中使用 resolver
指令直接设置使用的 nameserver
地址。
官方文档中是这么描述的:
Syntax: resolver address ... [valid=time] [ipv6=on|off];
Default: —
Context: http, server, location
一个简单的例子:
我们的代码常常运行在各种云上,为了减少维护成本,我采用了动态读取本机 /etc/resolv.conf
文件的方法。
废话不说,让我们一睹为快。
local pcall = pcall
local io_open = io.open
local ngx_re_gmatch = ngx.re.gmatch
local ok, new_tab = pcall(require, "table.new")
if not ok then
new_tab = function (narr, nrec) return {} end
end
local _dns_servers = new_tab(5, 0)
local _read_file_data = function(path)
local f, err = io_open(path, 'r')
if not f or err then
return nil, err
end
local data = f:read('*all')
f:close()
return data, nil
end
local _read_dns_servers_from_resolv_file = function()
local text = _read_file_data('/etc/resolv.conf')
it, err = ngx_re_gmatch(text, [[^nameserver\s+(\d+?\.\d+?\.\d+?\.\d+$)]], "jomi")
for captures, err in it do
if not err then
_dns_servers[#_dns_servers + 1] = captures[1]
end
end
end
_read_dns_servers_from_resolv_file()
通过上述代码我们成功动态拿到了一组 nameserver
的地址,下面就可以通过 resty.dns.resolver
大杀四方了。
我这边把解析的结果放入了 lrucache
缓存了 5 分钟,你们同样可以把结果放入 shared
中来减少 worker
查询次数。
现在我们已经实现了自缓存体系的 DNS 查询,如果搭配 resty.http
就会达到更好的效果。
发起 request
请求,addr
+ port
connect 之,设置 header
的 host
为 hostname
,path
等值来实现 IP 直接访问等高阶用法。
这里就不过多的阐述了。
local client = mysql:new()
client:connect({
host = _get_addr(conf.mysql_hostname),
port = 3306,
database = "test",
user = "test",
password = "123456"
还有些同学可能会在 hosts
文件中自定义域名和 IP,这时候 resolve
是无法正常解析的。
这个时候可以借助 dnsmasq
这个服务来缓存我们的 DNS 结果,hosts
的定义可以被该服务识别。
需要在 Nginx 的配置文件中,设置 resolver
为 dnsmasq
服务的监听地址即可。