動態指標
以往我們做一些伺服器上的指標資料統計,比如某個域名的訪問量最高的 10 個客戶端地址,某個域名的快取命中率,則需要伺服器將全量的指標資料上報到監控系統,再在監控系統中資料的聚合計算。
而動態指標功能支援以類似 SQL 語法的 Metric SQL 編寫聚合規則,在伺服器上高效地實時聚合計算得到統計資料,大大地減少了需要上報的資料量。Metric SQL 的語法可以參考這個文件:Metric SQL
。
動態指標的統計資料目前支援以 Lua API 和 Prometheus Exporter 的方式匯出。
這裡我們提供一個統計請求狀態碼分佈的實際例子。
建立動態指標
選擇新建動態指標,名稱填寫為 status-distribution,指標聚合上報間隔為 60 秒,SQL 內容如下:
select count(*) from reqs group by status;
匯出動態指標
點選編譯按鈕,然後可以從下面的編譯歷史中下載編譯後的 zip 壓縮包。
壓縮包中包含以下這些檔案,解壓後複製到 nginx.conf
中指定的 lua_package_path
目錄下。
Archive: Tool-1-dymetrics-status-distribution.zip
Length Date Time Name
--------- ---------- ----- ----
2383 01-26-2022 17:12 dymetrics.ljbc
0 01-26-2022 17:12 metrics/
59638 01-26-2022 17:12 metrics/status-distribution.ljbc
此外,在列表頁也可以透過多選的方式來匯出多個動態指標。
修改 nginx.conf 配置
動態指標需要修改 nginx.conf 配置才能使用,在 http block
內新增動態指標配置,示例是推薦配置的大小,可以根據實際情況調整。同時動態指標還依賴 openresty-yajl
,還需要在 lua_package_cpath
加上 openresty-yajl
的路徑。
lua_shared_dict dymetrics_keys 1m;
lua_shared_dymetrics dymetrics 100m;
lua_package_cpath "/usr/local/openresty-yajl/lib64/;./?.so;;";
新增動態指標初始化程式碼
在 init_worker
階段進行初始化,需要提供一個回撥函式。指標每個統計週期完成後會呼叫這個函式,在這裡將統計資料回傳。
init_worker_by_lua_block {
local report_func = function (data)
-- `data` is the result of the metric statistics
end
require "dymetrics" .init_worker(report_func)
}
新增動態指標採集入口
在 log_by_lua_block
階段新增採集入口。
log_by_lua_block {
require "dymetrics" .collect()
}
新增 Prometheus Exporter 介面
Prometheus 的資料可以從這個介面匯出。
location /prometheus {
content_by_lua_block {
require "dymetrics" .prometheus()
}
}
完整的 nginx.conf
worker_processes auto;
events {
worker_connections 1024;
}
http {
lua_package_path "$prefix/lua/?.lua;;";
lua_package_cpath "$prefix/lualib/?.so;/usr/local/openresty-yajl/lib64/?.so;;";
sendfile on;
keepalive_timeout 65;
lua_shared_dict dymetric_version 1m;
lua_shared_dymetrics dymetrics 100m;
init_worker_by_lua_block {
local report_func = function (data)
-- do nothing
end
require "dymetrics" .init_worker(report_func)
}
server {
listen 127.0.0.1:80;
server_name localhost;
location / {
root html;
index index.html index.htm;
log_by_lua_block {
require "dymetrics" .collect()
}
}
location /prometheus {
content_by_lua_block {
require "dymetrics" .prometheus()
}
}
}
}