openresty动态解析域名

废话不多说直接上代码

user  nobody;
worker_processes  auto;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections 100000 ;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;
    include nginx_status.conf;
}

stream {
    lua_shared_dict dns_cache 1m;
    
    init_worker_by_lua_block {
        local function update_dns()
            local resolver = require "resty.dns.resolver"
            local r, err = resolver:new{
			    -- 这里使用阿里云内网dns 请合理更换
                nameservers = {"100.100.2.138", {"100.100.2.136", 53}},
                retrans = 5,  -- 5 retransmissions on receive timeout
            }
    
            if not r then
                ngx.log(ngx.ERR, "failed to instantiate the resolver: ", err)
                return
            end
    
            local answers, err, tries = r:query("testcluster.redis.rds.aliyuncs.com", nil, {})
            if not answers then
                ngx.log(ngx.ERR, "failed to query the DNS server: ", err)
                return
            end
    
            if answers.errcode then
                ngx.log(ngx.ERR, "server returned error code: ", answers.errcode, ": ", answers.errstr)
                return
            end
    
            for i, ans in ipairs(answers) do
                if ans.address then
                    ngx.shared.dns_cache:set("myupstream", ans.address)
                    break
                end
            end
        end
    
        local ok, err = ngx.timer.at(0, update_dns)
        if not ok then
            ngx.log(ngx.ERR, "failed to create timer: ", err)
            return
        end
    
        local ok2, err2 = ngx.timer.every(30, update_dns)
        if not ok2 then
            ngx.log(ngx.ERR, "failed to create timer: ", err2)
            return
        end
    }

    log_format basic '$remote_addr [$time_local] '
                 '$protocol $status $bytes_sent $bytes_received '
                 '$session_time';

    access_log /data/logs/nginx-access.log basic buffer=32k; 


    log_format proxy '$remote_addr [$time_local] '
                 '$protocol $status $bytes_sent $bytes_received '
                 '$session_time "$upstream_addr" '
                 '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';


upstream linshibackend {
      server 0.0.0.1:1;  # just an invalid address placeholder
      balancer_by_lua_block {
          local balancer = require "ngx.balancer"
          local upstream = ngx.shared.dns_cache:get("myupstream")
          if not upstream then
              ngx.log(ngx.ERR, "failed to get upstream from dns_cache")
              return
          end

          local ok, err = balancer.set_current_peer(upstream, 19000)
          if not ok then
              ngx.log(ngx.ERR, "failed to set the current peer: ", err)
              return
          end
      }
}
server {
    listen 39000 so_keepalive=30m::10;
    proxy_pass linshibackend;
    access_log /logs/new.log proxy buffer=32k;
}
}

需要注意的几点

  1. lua_shared_dict 在 http 和 stream 上下文中都是独立的。也就是说,在 http 上下文中定义的 lua_shared_dict 在 stream 上下文中是不可见的,反之亦然。如果你在 stream 上下文中需要使用 dns_cache,你需要在 stream 上下文中重新定义它。所以本次我们是在stream中使用动态upstream,所以dict 初始化和 init work流程我们全部在stream 模块中执行。
  2. init 过程中不允许调用api阻塞初始化流程。所以dns请求过程要全部封装成函数update_dns。并使用ngx.timer.at 和 ngx.timer.every 后台执行。
posted @ 2023-12-12 17:45  萱乐庆foreverlove  阅读(29)  评论(0编辑  收藏  举报