nginx 返回动态Html,Nginx负载均衡-Nginx动态更新upstream
Nginx 的配置是啟動時一次性加載到內存中的,在實際的使用中,對 Nginx 服務器上游服務器組中節點的添加或移除仍需要重啟或熱加載 Nginx 進程。在 Nginx 的商業版本中,提供了 ngx_http_api_module 模塊,可以通過 API 動態添加或移除上游服務器組中的節點。
對于 Nginx 開源版本,通過 Nginx 的擴展版 OpenResty 及 Lua 腳本也可以實現上游服務器組中節點的動態操作,這里只使用 OpenResty 的 lua-upstream-nginx-module 模塊簡單演示節點的上下線狀態動態修改的操作。該模塊提供了 set_peer_down 指令,該指令可以對 upstream 的節點實現上下線的控制。
由于該指令只支持 worker 級別的操作,為使得 Nginx 的所有 worker 都生效,此處通過編寫 Lua 腳本與 lua-resty-upstream-healthcheck 模塊做了簡單的集成,利用 lua-resty-upstream-healthcheck 模塊的共享內存機制將節點狀態同步給其他工作進程,實現對 upstream 的節點狀態的控制。
首先在 OpenResty 的 lualib 目錄下創建公用函數文件 api_func.lua,lualib/api_func.lua 內容如下:
local _M = { _VERSION = '1.0' }
local cjson = require "cjson"
local upstream = require "ngx.upstream"
local get_servers = upstream.get_servers
local get_primary_peers = upstream.get_primary_peers
local set_peer_down = upstream.set_peer_down
# 分割字符串為table
local function split( str,reps )
local resultStrList = {}
string.gsub(str,"[^"..reps.."]+",function ( w )
table.insert(resultStrList,w)
end)
return resultStrList
end
# 獲取server列表
local function get_args_srv( args )
if not args["server"] then
ngx.say("failed to get post args: ", err)
return nil
else
if type(args["server"]) ~= "table" then
server_list=split(args["server"],",")
else
server_list=args["server"]
end
end
return server_list
end
# 獲取節點在upstream中的順序
local function get_peer_id(ups,server_name)
local srvs = get_servers(ups)
for i, srv in ipairs(srvs) do
-- ngx.print(srv["name"])
if srv["name"] == server_name then
target_srv = srv
target_srv["id"] = i-1
break
end
end
return target_srv["id"]
end
# 獲取節點共享內存key
local function gen_peer_key(prefix, u, is_backup, id)
if is_backup then
return prefix .. u .. ":b" .. id
end
return prefix .. u .. ":p" .. id
end
# 設置節點狀態
local function set_peer_down_globally(ups, is_backup, id, value,zone_define)
local u = ups
local dict = zone_define
local ok, err = set_peer_down(u, is_backup, id, value)
if not ok then
ngx.say(cjson.encode({code = "E002", msg = "failed to set peer down", data = err}))
end
local key = gen_peer_key("d:", u, is_backup, id)
local ok, err = dict:set(key, value)
if not ok then
ngx.say(cjson.encode({code = "E003", msg = "failed to set peer down state", data = err}))
end
end
# 獲取指定upstream的節點列表
function _M.list_server(ups)
local srvs, err = get_servers(ups)
ngx.say(cjson.encode(srvs))
end
# 設置節點狀態
function _M.set_server(ups,args,status,backup,zone_define)
local server_list = get_args_srv(args)
if server_list == nil then
ngx.say(cjson.encode({code = "E001", msg = "no args",data = server_list}))
return nil
end
for _, s in pairs(server_list) do
local peer_id = get_peer_id(ups,s)
if status then
local key = gen_peer_key("nok:", ups, backup, peer_id)
local ok, err = zone_define:set(key, 1)
set_peer_down_globally(ups, backup, peer_id, true,zone_define)
else
local key = gen_peer_key("ok:", ups, backup, peer_id)
local ok, err = zone_define:set(key, 0)
set_peer_down_globally(ups, backup, peer_id, nil,zone_define)
end
end
ngx.say(cjson.encode({code = "D002", msg = "set peer is success",data = server_list}))
end
return _M
Nginx 配置文件 status.conf 的內容如下:
# 關閉socket錯誤日志
lua_socket_log_errors off;
# 設置共享內存名稱及大小
lua_shared_dict _healthcheck_zone 10m;
init_worker_by_lua_block {
local hc = require "resty.upstream.healthcheck"
# 設置需要健康監測的upstream
local ups = {"foo.com","sslback"}
# 遍歷ups,綁定健康監測策略
for k, v in pairs(ups) do
local ok, err = hc.spawn_checker{
shm = "_healthcheck_zone", # 綁定lua_shared_dict定義的共享內存
upstream = v, # 綁定upstream指令域
type = "http",
http_req = "GET / HTTP/1.0\r\nHost: foo.com\r\n\r\n",
# 用以檢測的raw格式http請求
interval = 2000, # 每2s檢測一次
timeout = 1000, # 檢測請求超時時間為1s
fall = 3, # 連續失敗3次,被檢測節點被置為DOWN狀態
rise = 2, # 連續成功2次,被檢測節點被置為UP狀態
# 當健康檢測請求返回的響應碼為200或302時,被認
# 為檢測通過
valid_statuses = {200, 302},
concurrency = 10, # 健康檢測請求的并發數為10
}
if not ok then
ngx.log(ngx.ERR, "failed to spawn health checker: ", err)
return
end
end
}
upstream foo.com {
server 192.168.2.145:8080;
server 192.168.2.109:8080;
server 127.0.0.1:12356 backup;
}
upstream sslback {
server 192.168.2.145:443;
server 192.168.2.159:443;
}
server {
listen 18080;
access_log off;
error_log off;
# 健康檢測狀態頁
location = /healthcheck {
access_log off;
allow 127.0.0.1;
allow 192.168.2.0/24;
allow 192.168.101.0/24;
deny all;
default_type text/plain;
content_by_lua_block {
local hc = require "resty.upstream.healthcheck"
ngx.say("Nginx Worker PID: ", ngx.worker.pid())
ngx.print(hc.status_page())
}
}
location = /ups_api {
default_type application/json;
content_by_lua '
# 獲取URL參數
local ups = ngx.req.get_uri_args()["ups"]
local act = ngx.req.get_uri_args()["act"]
if act == nil or ups == nil then
ngx.say("usage: /ups_api?ups={name}&act=[down,up,list]")
return
end
# 引用api_func.lua腳本
local api_fun = require "api_func"
# 綁定共享內存_healthcheck_zone
local zone_define=ngx.shared["_healthcheck_zone"]
if act == "list" then
# 獲取指定upstream的節點列表
api_fun.list_server(ups)
else
ngx.req.read_body()
local args, err = ngx.req.get_post_args()
if act == "up" then
# 節點狀態將設置為UP
api_fun.set_server(ups,args,false,false,zone_define)
end
if act == "down" then
# 節點狀態將設置為DOWN
api_fun.set_server(ups,args,true,false,zone_define)
end
end
';
}
}
操作命令如下:
# 查看upstream foo.com的服務器列表
curl “http://127.0.0.1:18080/ups_api?act=list&ups=foo.com”
# 將192.168.2.145:8080這個節點設置為DOWN狀態
curl -X POST -d “server=192.168.2.145:8080” “http://127.0.0.1:18080/ups_api?act= down&ups=foo.com”
# 將192.168.2.145:8080這個節點設置為UP狀態
curl -X POST -d “server=192.168.2.145:8080” “http://127.0.0.1:18080/ups_api?act= up&ups=foo.com”
總結
以上是生活随笔為你收集整理的nginx 返回动态Html,Nginx负载均衡-Nginx动态更新upstream的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win10笔记本如何连接打印机
- 下一篇: 电信光猫强制wifi(SSID)名称Ch