nginx-通過lua動態更改upstream
最近我們搭了一個consul服務,開發同學想要把supervisor的web管理整合到consul中,需要根據url中給定的ip地址動態的載入該機器上的supervisor管理介面,因為服務端機器都在VPC內部,辦公網網路不可達,因此不能簡單的rewrite url或者做個重定向來解決,因此需要通過反向代理的方式將請求轉發給後端機器,並且要實現反向代理伺服器的動態更改,由於邏輯比較複雜,所以就用lua指令碼來實現了
大致邏輯是這樣的
-
upstream獲取
- 因為我們的consul服務通過域名訪問,鏈到supervisor時,url中會有具體的upstream Ip,所以會先從url中看是否能match到ip,這樣可以拿到upstream,並返回supervisor首頁資訊;
- 當做tailf,start, stop 操作時,因為頁面是從supervisor頁鏈過去的,所以可以通過http_referer header來match upstream ip
-
uri獲取
- 當拿到upstream後,從request_uri做字串擷取來拿到uri
- 然後一些css樣式,image可以從本機獲取
具體實現如下:
location /supervisor/ {
set $query_uri "";
#一開始從request_uri中把/supervisor/字首去掉
if ($request_uri ~* "/supervisor/(.*)") {
set $query_uri $1;
}
set $upstreamhost "";
rewrite_by_lua_block {
ngx.var.upstreamhost = string.match(ngx.var.query_uri,"%d+.%d+.%d+.%d+")
if ngx.var.upstreamhost == nil then
ngx.var.upstreamhost = string.match(ngx.var.http_referer,"%d+.%d+.%d+.%d+")
end
index_start,index_end = string.find(ngx.var.query_uri,ngx.var.upstreamhost)
if index_end ~= nil then
tmp_uri = string.sub(ngx.var.query_uri,index_end+1)
ngx.var.query_uri = tmp_uri
end
}
proxy_pass http://$upstreamhost:8555/$query_uri;
proxy_redirect http://$upstreamhost:8555 http://consul.url/supervisor/$upstreamhost;
}
location /supervisor/images/ {
if ($request_uri ~* "/supervisor/(.*)") {
proxy_pass http://127.0.0.1:8555/$1;
}
}
location /supervisor/stylesheets/ {
if ($request_uri ~* "/supervisor/(.*)") {
proxy_pass http://127.0.0.1:8555/$1;
}
}
因為在supervisor管理頁面clear log的時候,伺服器會返回Location header,所以通過proxy_redirect directive來做個重定向,讓client(瀏覽器)還是走consul.server來傳送請求,從而避免網路不可達問題
這樣從本地辦公網訪問http://consul.url/supervisor/10.10.10.12
就可以不用登陸伺服器對服務進行啟停及檢視日誌等操作了
pprof整合
同樣再加pprof(go的效能除錯工具)的時候,就可以複用這個邏輯了(因為go的pprof埠不一致,所以在url中給了ip:port, match的時候也多改成了”%d+.%d+.%d+.%d+:%d+”)
location /debug/pprof/ {
set $query_uri "";
if ($request_uri ~* "/debug/pprof/(.*)") {
set $query_uri $1;
}
set $upstreamhost "";
rewrite_by_lua_block {
ngx.var.upstreamhost = string.match(ngx.var.query_uri,"%d+.%d+.%d+.%d+:%d+")
if ngx.var.upstreamhost == nil then
ngx.var.upstreamhost = string.match(ngx.var.http_referer,"%d+.%d+.%d+.%d+:%d+")
end
index_start,index_end = string.find(ngx.var.query_uri,ngx.var.upstreamhost)
if index_end ~= nil then
tmp_uri = string.sub(ngx.var.query_uri,index_end+1)
ngx.var.query_uri = tmp_uri
end
}
proxy_pass http://$upstreamhost/debug/pprof/$query_uri;
}
這樣開發從辦公環境訪問http://consul.url/pprof/10.10.10.12:203
就可以對測試、開發環境的go程式進行簡單的監控了
改進: ip全部通過url獲取
有時開發希望通過命令列直接去看某臺機器的pprof debug資訊,為了方便貼上瀏覽器的url,所以希望能把host地址包含進請求url,所以做了如下改進
location /debug/pprof/ {
set $query_uri "";
if ($request_uri ~* "/debug/pprof/(.*)") {
set $query_uri $1;
}
set $upstreamhost "";
rewrite_by_lua_block {
ngx.var.upstreamhost = string.match(ngx.var.query_uri,"%d+.%d+.%d+.%d+:%d+")
if ngx.var.upstreamhost == nil then
ngx.var.upstreamhost = string.match(ngx.var.http_referer,"%d+.%d+.%d+.%d+:%d+")
end
index_start,index_end = string.find(ngx.var.query_uri,ngx.var.upstreamhost)
if index_end ~= nil then
tmp_uri = string.sub(ngx.var.query_uri,index_end+2)
ngx.var.query_uri = tmp_uri
end
local new_uri = "/debug/pprof/"..ngx.var.upstreamhost.."/"..ngx.var.query_uri
--ngx.redirect(new_uri,301)
ngx.req.set_uri(new_uri)
}
proxy_pass http://$upstreamhost/debug/pprof/$query_uri;
}
這樣從http://consul.url/pprof/10.10.10.12:203
返回的連結檢視goroutine資訊的時候,瀏覽器會跳轉到http://consul.url/pprof/10.10.10.12:203/goroutine?debug=1
關於多餘程式碼
如果set_uri了,那麼下面這句程式碼看似就顯得多餘了
if ngx.var.upstreamhost == nil then
ngx.var.upstreamhost = string.match(ngx.var.http_referer,"%d+.%d+.%d+.%d+:%d+")
end
但是瀏覽器有個不好的地方就是會快取重定向,而且單純的disable cache不管用,因為之前都是跳到http://consul.url/pprof/goroutine?debug=1
, 所以即使set_uri, 瀏覽器仍然不會跳轉到新的url,只有先301重定向破壞它的‘記憶’後才可以正常跳轉
相關文章
- 通過crontab更改DataGuard物理庫managed recover狀態
- 編譯lua動態庫編譯
- 通過字串動態建立類物件字串物件
- openresty通過lua增加隨機traceidREST隨機
- APEX 通過PL/SQL動態展示區域中動態內容SQL
- 通過類名動態生成物件物件
- 通過Java反射動態獲取資訊Java反射
- 通過減少動態派送提升效能
- OpenResty + Lua 動態增加 Zuul 節點RESTZuul
- vue如何通過變數動態拼接urlVue變數
- lua——alien庫實現lua呼叫C動態連結庫(dll、so)
- 透過例子學習Lua(5)--Lua與C的互動(轉)
- Laravel 通過子查詢建立動態關聯Laravel
- JavaScript動態更改引入樣式表JavaScript
- Flutter 動態更改應用程式啟動圖示Flutter
- 通過Android應用更改系統時間Android
- 動態更改svg圖片的顏色SVG
- 透過crontab更改DataGuard物理庫managed recover狀態
- 關於 Lumen 如何通過動態版本號配置路由資訊。路由
- Nginx-基礎Nginx
- nginx-安裝Nginx
- 詳解 APISIX Lua 動態除錯外掛 inspectAPI除錯
- c#通過反射動態執行類的例項及靜態方法C#反射
- leaflet動態更改wms瓦片請求引數
- 通過url動態獲取圖片大小方法總結
- Scrapy框架-通過scrapy_splash解析動態渲染的資料框架
- 直播軟體開發,通過js動態設定字型大小JS
- 通過vue元件化方式實現常見動態圖示Vue元件化
- pb通過類名稱動態構建類物件(原創)物件
- 通過v$parameter 檢視 issys_modifiable 狀態判斷是否動態引數
- Nginx利用Lua+Redis實現動態封禁IP的方法NginxRedis
- SpringBoot(18)---通過Lua指令碼批量插入資料到Redis布隆過濾器Spring Boot指令碼Redis過濾器
- 通過建立動態型別 動態構建Expression Select表示式來控制Property可見性型別Express
- Nginx-基礎篇Nginx
- 通過Oracle動態效能檢視採集查詢調優數Oracle
- 透過例子學習Lua(2)---Lua流程控制(轉)
- VueJs中動態更改svg的相關屬性VueJSSVG
- 透過例子學習Lua(3)----Lua資料結構(轉)資料結構