41.5 nginx拦截prometheus查询请求使用lua脚本做promql的检查替换

本节重点介绍 :

  • 编写lua脚本做promql的检查替换
  • nginx拦截prometheus查询请求使用lua处理

编写lua脚本做promql的检查替换

获取请求参数

shell 复制代码
function replace_work()
    --Nginx服务器中使用lua获取get或post参数

    local request_method = ngx.var.request_method;
    local args = {}
    --获取参数的值

    if "GET" == request_method then
        args = ngx.req.get_uri_args();
    elseif "POST" == request_method then
        ngx.req.read_body();
        args = ngx.req.get_post_args();
    end

    local q_query = args["query"];
    local q_start = args["start"];
    local q_end = args["end"];
    local q_step = args["step"];
end

根据查询的promql算m5d

shell 复制代码
    local md5_str = get_str_md5(q_query)

    if md5_str == null then
        return
    end
function get_str_md5(input_s)
    local resty_md5 = require "resty.md5"
    local md5 = resty_md5:new()
    if not md5 then
        ngx.log(ngx.ERR, "failed to create md5 object")
        return
    end

    local ok = md5:update(input_s)
    if not ok then
        ngx.log(ngx.ERR, "failed to add data")
        return
    end
    local digest = md5:final()

    local str = require "resty.string"
    local md5_str = str.to_hex(digest)
    return md5_str
end

根据md5去redis中query

shell 复制代码
    local redis_query_key = "hke:heavy_expr:" .. md5_str
    --ngx.log(ngx.ERR, "redis_query_key: ",redis_query_key)
    local redis_get_res = redis_get(redis_query_key)
    if redis_get_res == true then
        q_query = redis_query_key
    end
function redis_get(key)
    -- start of redis

    local redis = require "resty.redis"
    local red = redis:new()
    --red:set_timeouts(1000, 1000, 1000)
    local ok, conn_err = red:connect("localhost", 6379)
    if not ok then
        ngx.log(ngx.ERR, "[redis]failed to connect redis server:", conn_err)
        return false
    end

    local res, get_err = red:get(key)
    if get_err then
        ngx.log(ngx.ERR, "[redis]failed to get value by key: ", key, "err:", get_err)
        return false
    end

    red:set_keepalive(30000, 1000)
    if res ~= ngx.null then
        ngx.log(ngx.INFO, "[redis]success  get value by key: ", key, "value: ", res)
        return true
    else
        return false
    end

    -- end of  redis
end

如果redis中有结果,就替换查询语句为聚合后的

shell 复制代码
    if redis_get_res == true then
        q_query = redis_query_key
    end

    local new_args = {}
    new_args["query"] = q_query
    new_args["start"] = q_start
    new_args["end"] = q_end
    new_args["step"] = q_step

    ngx.req.set_uri_args(new_args)
    --ngx.req.set_uri_args("end=" .. q_end)
    --local arg = ngx.req.get_uri_args()
    --for k, v in pairs(arg) do
    --    ngx.say("[GET ] key:", k, " v:", v)
    --end

完整的 prome_redirect.lua

shell 复制代码
function get_str_md5(input_s)
    local resty_md5 = require "resty.md5"
    local md5 = resty_md5:new()
    if not md5 then
        ngx.log(ngx.ERR, "failed to create md5 object")
        return
    end

    local ok = md5:update(input_s)
    if not ok then
        ngx.log(ngx.ERR, "failed to add data")
        return
    end
    local digest = md5:final()

    local str = require "resty.string"
    local md5_str = str.to_hex(digest)
    return md5_str
end

function redis_get(key)
    -- start of redis

    local redis = require "resty.redis"
    local red = redis:new()
    --red:set_timeouts(1000, 1000, 1000)
    local ok, conn_err = red:connect("localhost", 6379)
    if not ok then
        ngx.log(ngx.ERR, "[redis]failed to connect redis server:", conn_err)
        return false
    end

    local res, get_err = red:get(key)
    if get_err then
        ngx.log(ngx.ERR, "[redis]failed to get value by key: ", key, "err:", get_err)
        return false
    end

    red:set_keepalive(30000, 1000)
    if res ~= ngx.null then
        ngx.log(ngx.INFO, "[redis]success  get value by key: ", key, "value: ", res)
        return true
    else
        return false
    end

    -- end of  redis
end

function replace_work()
    --Nginx服务器中使用lua获取get或post参数

    local request_method = ngx.var.request_method;
    local args = {}
    --获取参数的值

    if "GET" == request_method then
        args = ngx.req.get_uri_args();
    elseif "POST" == request_method then
        ngx.req.read_body();
        args = ngx.req.get_post_args();
    end

    local q_query = args["query"];
    local q_start = args["start"];
    local q_end = args["end"];
    local q_step = args["step"];

    local md5_str = get_str_md5(q_query)

    if md5_str == null then
        return
    end
    local redis_query_key = "hke:heavy_expr:" .. md5_str
    --ngx.log(ngx.ERR, "redis_query_key: ",redis_query_key)
    local redis_get_res = redis_get(redis_query_key)
    if redis_get_res == true then
        q_query = redis_query_key
    end

    local new_args = {}
    new_args["query"] = q_query
    new_args["start"] = q_start
    new_args["end"] = q_end
    new_args["step"] = q_step

    ngx.req.set_uri_args(new_args)
    --ngx.req.set_uri_args("end=" .. q_end)
    --local arg = ngx.req.get_uri_args()
    --for k, v in pairs(arg) do
    --    ngx.say("[GET ] key:", k, " v:", v)
    --end

end

return replace_work();

nginx拦截prometheus查询请求使用lua处理

  • ngx_prome_redirect.conf
shell 复制代码
# 真实prometheus后端,使用前请修改
upstream real_prometheus {

       server 1.1.1.1:9090;
       server 2.2.2.2:9090;

}



server{
    listen 9992;
    server_name _;
    location / {  
        proxy_set_header Host $host:$server_port;
        proxy_pass http://real_prometheus;
    } 
    location /api/v1/query_range { 
        access_by_lua_file /usr/local/openresty/nginx/lua_files/prome_redirect.lua;
        proxy_pass http://real_prometheus;
    }
      
    
}
  • grafana发来的请求经过nginx,使用lua脚本处理
  • 然后转发到真实的prometheus 查询

本节重点总结 :

  • 编写lua脚本做promql的检查替换
  • nginx拦截prometheus查询请求使用lua处理
相关推荐
*郑*10 小时前
nginx配置反向代理后端
运维·nginx
霍志杰13 小时前
网址为 http://xxx:xxxx/的网页可能暂时无法连接,或者它已永久性地移动到了新网址
nginx
hnlucky14 小时前
《基于 Kubernetes 的 WordPress 高可用部署实践:从 MariaDB 到 Nginx 反向代理》
运维·数据库·nginx·云原生·容器·kubernetes·mariadb
·云扬·16 小时前
【PmHub后端篇】PmHub中基于Redis加Lua脚本的计数器算法限流实现
redis·算法·lua
铁锚16 小时前
一个WordPress连续登录失败的问题排查
java·linux·服务器·nginx·tomcat
猴子请来的逗比48920 小时前
tomcat与nginx之间实现多级代理
java·nginx·tomcat
matrixlzp1 天前
Nginx 源码安装成服务
nginx·云原生
Aric_Jones1 天前
lua入门语法,包含安装,注释,变量,循环等
java·开发语言·git·elasticsearch·junit·lua
π大星星️1 天前
HAProxy + Keepalived + Nginx 高可用负载均衡系统
运维·nginx·负载均衡
Johny_Zhao1 天前
K8S+nginx+MYSQL+TOMCAT高可用架构企业自建网站
linux·网络·mysql·nginx·网络安全·信息安全·tomcat·云计算·shell·yum源·系统运维·itsm