nginx中添加lua模块,结合exporter计算内存使用率动态负载均衡调度

一、nginx中添加lua模块

1、安装依赖

yum install gcc gcc++ readline-devel wget vim bash-completion  pcre pcre-devel zlib zlib-devel openssl openssl-devel unzip lua lua-devel -y

2、编译安装luajit2

wget https://github.com/openresty/luajit2/archive/refs/tags/v2.1-20241113.tar.gz
tar -xf v2.1-20241113.tar.gz
cd luajit2-2.1-20241113
make install PREFIX=/usr/local/LuaJIT
export LUAJIT_LIB=/usr/local/LuaJIT/lib
export LUAJIT_INC=/usr/local/LuaJIT/include/luajit-2.1

3、安装ngx_devel_kit

wget https://github.com/vision5/ngx_devel_kit/archive/refs/tags/v0.3.3.tar.gz
tar -xf v0.3.3.tar.gz
mv ngx_devel_kit-0.3.3 ngx_devel_kit

4、安装lua-nginx-module

wget https://github.com/openresty/lua-nginx-module/archive/refs/tags/v0.10.19.tar.gz
tar -xf v0.10.19.tar.gz
mv lua-nginx-module-0.10.19 lua-nginx-module

5、编码安装nginx

wget http://nginx.org/download/nginx-1.21.1.tar.gz
tar -xf nginx-1.21.1.tar.gz
cd nginx-1.21.1/
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_realip_module --with-http_sub_module --with-http_gzip_static_module --with-pcre --with-ld-opt=-Wl,-rpath,/usr/local/LuaJIT/lib --add-module=../ngx_devel_kit --add-module=../lua-nginx-module
 make
make install

6、安装第三方lua脚本

复制代码
#################lua-resty-core################
wget  https://github.com/openresty/lua-resty-core/archive/refs/tags/v0.1.21.tar.gz
tar -xf v0.1.21.tar.gz
cd lua-resty-core-0.1.21/
make install PREFIX=/usr/local/nginx

###############lua-resty-lrucache###############
wget https://github.com/openresty/lua-resty-lrucache/archive/refs/tags/v0.12.tar.gz
tar -xf v0.12.tar.gz
cd lua-resty-lrucache-0.12
make install PREFIX=/usr/local/nginx

###############lua-resty-http###############
wget https://github.com/ledgetech/lua-resty-http/archive/refs/tags/v0.17.2.tar.gz
tar -xf v0.17.2.tar.gz
cd lua-resty-http-0.17.2/
make install PREFIX=/usr/local/nginx

###############lua-resty-string###############
wget https://github.com/openresty/lua-resty-string/archive/refs/tags/v0.16.tar.gz
tar -xf v0.16.tar.gz
cd lua-resty-string-0.16/
make install PREFIX=/usr/local/nginx
复制代码

二、通过内存使用率动态负载均衡调度

1、自定义lua脚本获取后端服务器内存值

metrics.lua脚本如下
复制代码
ngx.header["Content-Type"] = "text/html; charset=utf-8"
local http = require("resty.http")

-- 函数:解析指标并计算内存使用率
local function get_memory_usage(ip)
    local exporter_url = "http://" .. ip .. ":9182/metrics"
    ngx.log(ngx.INFO, exporter_url)
    local httpc = http.new()
    local res, err = httpc:request_uri(exporter_url)
    if not res then
        ngx.say("Failed to get metrics: ", err)
        return nil
    end
    local metrics = res.body
    local total_memory = 0
    local free_memory = 0
    for line in metrics:gmatch("[^\r\n]+") do
        if line:match("windows_cs_physical_memory_bytes%s+") then
            total_memory = tonumber(line:match("windows_cs_physical_memory_bytes%s+(%d+%.?%d*[eE]?[+-]?%d*)"))
        elseif line:match("windows_os_physical_memory_free_bytes%s+") then
            free_memory = tonumber(line:match("windows_os_physical_memory_free_bytes%s+(%d+%.?%d*[eE]?[+-]?%d*)"))
        end
    end

    if not (total_memory and free_memory) then
        ngx.log(ngx.ERR, "Missing 'total_memory' or 'free_memory' field in JSON data")
        return nil
    end    

    return ((total_memory - free_memory) / total_memory) * 100
end


local function get_host_list()
   local nodes = {
       { host = "192.168.1.10"},
       { host = "192.168.1.11" }
   }
  
   local available_nodes = {}
   for _, node in ipairs(nodes) do
      local memory_usage = tonumber(get_memory_usage(node.host))
      --ngx.log(ngx.ERR, "ST3", node.host, memory_usage)
      if memory_usage <= 10 then
         table.insert(available_nodes, {host = node.host, memory_usage = memory_usage })
      end 
   end

   if table.getn(available_nodes) == 0 then
     ngx.header["Content-Type"] = "text/html; charset=utf-8"
      ngx.say("no resourse.")
      ngx.exit(500)
   end
   
   local select_host = available_nodes[math.random(1, table.getn(available_nodes))];
   ngx.log(ngx.ERR, "select ip: ", select_host.host, ".....select ip memory_usage: ", select_host.memory_usage)
   return select_host.host
end

return {
  get_memory_usage = get_memory_usage,
  get_host_list = get_host_list
} 
复制代码

2、配置nginx负载均衡策略

nginx配置如下

复制代码
#user  nobody;
worker_processes  1;

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

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    lua_package_path "/usr/local/nginx/lib/lua/?.lua;;";
    #lua_package_path "/usr/local/openresty/lualib/?.lua;/usr/local/openresty/lualib/?/init.lua;;";

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

   lua_shared_dict balancer_data 1m;

   init_by_lua_block {
        local shared = ngx.shared.balancer_data
        shared:set("backend_str", "")
   }

   upstream backend {
      server 0.0.0.0;

      balancer_by_lua_block {
        local balancer = require "ngx.balancer"
        local shared = ngx.shared.balancer_data

        local backend_str = shared:get("backend_str")
        local ok, err = balancer.set_current_peer(backend_str, 9182)
        if not ok then
           ngx.log(ngx.ERR, "failed to set the current peer: ", err)
           ngx.exit(500)
        end

      }
    }

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

location /metrics { 
  access_by_lua_block {
    local shared = ngx.shared.balancer_data

    local metrics = dofile "/usr/local/nginx/lua/metrics.lua"
    local ip = metrics.get_host_list()
    --ngx.log(ngx.ERR,"ST-zhirong2 :", ip)
    shared:set("backend_str", ip) 
  }
  proxy_pass http://backend/metrics;
 }
}
复制代码

 

posted @   流年晕开时光  阅读(153)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
历史上的今天:
2018-12-06 基于centos7.x系列docker自动部署脚本
点击右上角即可分享
微信分享提示