ARMS收斂機制說明
什么是收斂
ARMS探針在運行過程中會采集很多指標(biāo)數(shù)據(jù)(例如請求量、耗時、錯誤數(shù)等),為了能夠提供豐富、準(zhǔn)確的監(jiān)控信息,指標(biāo)中會攜帶一些維度信息(例如機器、接口等)。由于各種原因,有些維度會出現(xiàn)發(fā)散的情況,即高基數(shù)問題。高基數(shù)問題不僅會給存儲系統(tǒng)帶來巨大的壓力,造成寫入丟失、查詢緩慢等問題,也會導(dǎo)致用戶的賬單暴漲。為解決該問題,ARMS提供了相應(yīng)的收斂機制,一方面可用于解決高基數(shù)問題本身,即將維度的基數(shù)控制在合理的范圍內(nèi),另一方面也可用于標(biāo)記真實的觀測維度。例如用戶對外提供了RESTful形式的用戶服務(wù),其中包含一個查詢用戶信息的/api/v1/users/{ID}/info接口,如果直接記錄原始的請求URL,由于ID的變化,將會記錄一堆不同的URL,顯然這會造成高基數(shù)問題,另外還會導(dǎo)致用戶無法直觀地獲取到接口性能指標(biāo)。本文將逐一介紹ARMS現(xiàn)有的收斂機制,以幫助您了解收斂發(fā)生的原因及收斂結(jié)果所代表的含義。
收斂結(jié)果說明
ARMS已有的收斂結(jié)果及對應(yīng)的原因概括如下,更詳細(xì)的部分請參見下文。
收斂結(jié)果 | 收斂原因 |
{ARMS_IP}:80 | 訪問同一端口的IP數(shù)量過多,超過閾值(默認(rèn)50)。 |
{ARMS_STATIC_REQ} 或 {ARMS_S_XXX} | URL為靜態(tài)資源相關(guān)的請求。 |
{ARMS_ATTACK_REQ} | URL中包含攻擊字符串。 |
{ARMS_PARAMED_REQ} | URL中攜帶了參數(shù)。 |
{ARMS_OTHERS} | 單位時間內(nèi),記錄的維度值超過了允許的上限。 說明 默認(rèn)上限閾值詳細(xì)請參見下文基數(shù)空間收斂。 |
{ARMS_NUMBER} | URL中以 |
{ARMS_WORD} | URL中以 |
{ARMS_ANY} | URL中以 |
{XXX} | 使用了SpringController中的注解。 |
含有*的字符串 說明 僅適用于探針版本小于4.x的情況。 | 基于探針端的內(nèi)存統(tǒng)計機制對發(fā)散的部分進(jìn)行了收斂。 |
收斂機制說明
以下所有收斂機制都是默認(rèn)開啟的。除基數(shù)空間收斂外,所有收斂機制均支持用戶手動關(guān)閉。
不同的收斂機制支持的數(shù)據(jù)類型不同,每個收斂機制都會注明所支持的數(shù)據(jù)類型。
Spring注解收斂
對傳統(tǒng)的Web API來說,直接以請求URL作為維度值不會有任何問題,但對于RESTful形式的API或URL中包含變量的API來說,直接記錄請求URL將會導(dǎo)致維度發(fā)散。因此,對于使用了Spring Web框架的應(yīng)用,ARMS會嘗試提取相應(yīng)的注解信息(例如@RequestMapping)作為接口的維度值。
收斂邏輯
讀取Spring URL路由注解中的Path信息。
收斂結(jié)果
路由注解中配置的Value。
支持的數(shù)據(jù)類型
URL:僅適用于對外提供服務(wù)的URL,對于外部URL不適用。
收斂發(fā)生位置
探針端
支持的探針版本
2.9.1.2及以上版本
示例
下述APIController定義了一個獲取用戶信息的接口,其中使用了Path Variable。在采集接口數(shù)據(jù)時,將提取其注解(/api/v1/user/{userId}/info)作為最終的接口。
@RestController
@RequestMapping("/api/v1")
public class APIController {
@RequestMapping("/user/{userId}/info")
public String getUserInfo(@PathVariable("userId") String userId) {
return "hello " + userId;
}
}
收斂結(jié)果:
/api/v1/user/1234/info
被收斂為/api/v1/user/{userId}/info
。
基于內(nèi)存統(tǒng)計的收斂
對于未使用Spring Web框架的應(yīng)用或注解提取失敗的場景,將使用基于內(nèi)存統(tǒng)計的收斂算法進(jìn)行收斂。
僅適用于4.X以下版本的探針。
收斂邏輯
對每一個輸入使用預(yù)設(shè)的切分符號(/、=等)進(jìn)行切割,識別出一組單詞N。
對每個位置的單詞,統(tǒng)計其不重復(fù)的個數(shù)(即基數(shù)),當(dāng)個數(shù)超過設(shè)置閾值時,該位置的單詞就會變?yōu)?code data-tag="code" code-type="xCode" class="code">*。
收斂結(jié)果
包含*
的字符串
支持的數(shù)據(jù)類型
任意
收斂發(fā)生位置
探針端
支持的探針版本
2.x及以上版本且小于4.X版本
示例
應(yīng)用A中對外提供一個用戶信息查詢接口,請求方式為/api/v1/user/${userId}/info
,其中$userId填寫具體的userId。由于存在大量的userId, 內(nèi)存統(tǒng)計模塊會發(fā)現(xiàn)$userId存在發(fā)散的情況,便會將其收斂
為 /api/v1/user/*/info
自定義收斂
該功能支持用戶自定義一些收斂規(guī)則,來滿足一些特定的收斂需求。
收斂邏輯
逐一匹配用戶配置的收斂規(guī)則,如果命中,則結(jié)束。
收斂結(jié)果
以用戶配置為準(zhǔn)。
支持的數(shù)據(jù)類型
URL
收斂觸發(fā)位置
4.x及以上版本觸發(fā)于探針端
4.x以下版本觸發(fā)于服務(wù)端
支持的探針版本
所有
示例
用戶配置的規(guī)則:匹配/api/v1/user/[\d]+/info
,收斂為/api/v1/getUserInfo
。
對于所有命中/api/v1/user/[\d]+/info
正則表達(dá)式的請求將都被收斂為/api/v1/getUserInfo
。
靜態(tài)資源收斂
正常情況下,ARMS并不會監(jiān)控靜態(tài)資源相關(guān)請求。由于一些歷史原因,老舊的探針會采集靜態(tài)資源相關(guān)的指標(biāo)數(shù)據(jù),鑒于大多數(shù)情況下靜態(tài)資源并不具備監(jiān)控價值且資源URL變化頻繁,默認(rèn)開啟收斂。
收斂邏輯
檢查請求URL后綴是否命中默認(rèn)的靜態(tài)資源擴展名,如命中則會被收斂。
默認(rèn)的靜態(tài)資源擴展名:.log .7z .tgz .jpg .jpeg .png .gif .css .js .ico .woff2 .xml .svg .pdf .txt .text .ppt .word .xlsx .tar.gz .tar.bz2 .sh .yml .yaml .zip .log .gz .ttf .woff .eot .rar .properties
收斂結(jié)果
默認(rèn)為{ARMS_STATIC_REQ}
,開啟高級選項時(如有需要可提工單開啟),收斂結(jié)果中將包含資源后綴名。
支持的數(shù)據(jù)類型
URL
收斂觸發(fā)位置
4.x及以上版本觸發(fā)于探針端
4.x以下版本觸發(fā)于服務(wù)端
支持的探針版本
所有
示例
/api/v1/hello.jpg
默認(rèn)收斂為{ARMS_STATIC_REQ}
,開啟高級選項時,收斂為{ARMS_S_JPG}
。
攻擊請求收斂
根據(jù)經(jīng)驗,用戶服務(wù)可能會受到一些莫名的攻擊請求(例如嘗試讀取/etc/passwd文件),這些請求是被攻擊者構(gòu)造出來的,變化頻繁,記錄下來會給存儲帶來較大壓力。
收斂邏輯
檢查URL中是否含有攻擊字符,如存在則會被收斂。
默認(rèn)的攻擊字符:` $ \ ' !
收斂結(jié)果
{ARMS_ATTACK_REQ}
支持的數(shù)據(jù)類型
URL
收斂觸發(fā)位置
4.x及以上版本觸發(fā)于探針端
4.x以下版本觸發(fā)于服務(wù)端
支持的探針版本
所有
示例
/app/v1/user/info?cmd=`more /etc/passwd`
收斂為{ARMS_ATTACK_REQ}
。
帶參請求收斂
默認(rèn)情況下,探針在采集URL時并不會獲取參數(shù)信息,但依然存在部分場景下采集到的URL中包含了查詢參數(shù),由于查詢參數(shù)不可控,極易導(dǎo)致維度發(fā)散。
收斂邏輯
判斷URL中是否帶有查詢參數(shù),如果存在則進(jìn)行收斂。
默認(rèn)的查詢參數(shù)分隔符:; ? &
收斂結(jié)果
默認(rèn)為{ARMS_PARAMED_REQ},開啟高級選項時(如有需要可提工單開啟),收斂結(jié)果將保留URL部分,參數(shù)部分使用{ARMS_REQ_PARAMS}進(jìn)行替換。
支持的數(shù)據(jù)類型
URL
收斂觸發(fā)位置
4.x及以上版本觸發(fā)于探針端
4.x以下版本觸發(fā)于服務(wù)端
支持的探針版本
所有
示例
/api/v1/user/info?userId=12345
默認(rèn)收斂為{ARMS_PARAMED_REQ}
,開啟高級選項時,收斂為/api/v1/user/info?{ARMS_REQ_PARAMS}
。
無意義單詞收斂
一般來說,一個URL中如果含有長度過長的單詞或數(shù)字,該URL大概率會發(fā)散,為了盡量減少發(fā)散的情況。ARMS默認(rèn)會對過長的單詞或數(shù)字進(jìn)行替換。
收斂邏輯
以/
切分URL,結(jié)果記為term數(shù)組,遍歷term數(shù)組,針對每個term判斷其長度是否超過下述閾值,如果超過則會進(jìn)行替換。
單詞最大長度:64
純數(shù)字最大長度:10
單詞中包含的數(shù)字最大長度:10
收斂結(jié)果
過長的數(shù)字被收斂為:{ARMS_NUMBER}
過長的單詞被收斂為:{ARMS_WORD}
單詞中包含的數(shù)字過長被收斂為:{ARMS_ANY}
支持的數(shù)據(jù)類型
URL
收斂觸發(fā)位置
4.x及以上版本觸發(fā)于探針端
4.x以下版本觸發(fā)于服務(wù)端
支持的探針版本
所有
示例
/api/2024040710/hello2024040710
將被收斂為/api/{ARMS_NUMBER}/{ARMS_ANY}
。
智能收斂
經(jīng)過上文幾個收斂動作后,依然有可能存在大量發(fā)散的URL被記錄下來,針對這部分URL,ARMS會周期性基于算法自動計算出相應(yīng)的收斂規(guī)則,然后替換掉原始的URL。
收斂邏輯
邏輯較為復(fù)雜,此處僅做簡單介紹。
基于算法對樣本URL進(jìn)行分組。
對每個分組內(nèi)的URL Pattern進(jìn)行收斂處理,生成收斂規(guī)則。
合并各分組的收斂規(guī)則。
收斂結(jié)果
發(fā)散部分如果為純數(shù)字,將被替換為{ARMS_NUMBER}。
發(fā)散部分如果為純字母,將被替換為{ARMS_WORD}。
發(fā)散部分如果同時包含數(shù)字和字母,將被替換為{ARMS_ANY}。
支持的數(shù)據(jù)類型
URL
收斂觸發(fā)位置
4.x及以上版本觸發(fā)于探針端
4.x以下版本觸發(fā)于服務(wù)端
支持的探針版本
所有
示例
/api/product/1/info
/api/product/2/info
....
/api/product/N/info
服務(wù)端經(jīng)過計算后,會生成收斂規(guī)則:/api/product/[\d]+/info
(正則匹配)
收斂結(jié)果為/api/product/{ARMS_NUMBER}/info
。
后續(xù)符合上述正則的請求,都將被收斂為/api/product/{ARMS_NUMBER}/info
。
SQL規(guī)整化
由于多種情況的存在(例如分庫分表、注釋、明文),探針很可能會采集到大量SQL。基于這種情況,ARMS默認(rèn)會對每條SQL進(jìn)行處理,替換掉可能發(fā)散的部分。
規(guī)整邏輯
邏輯較為復(fù)雜,此處僅做簡單介紹。
注釋移除。
明文替換。
分庫分表名替換。
...
規(guī)整結(jié)果
替換掉發(fā)散部分后的結(jié)果。
支持的數(shù)據(jù)類型
SQL
收斂發(fā)生位置
探針端
支持的探針版本
4.X 及以上版本
示例
select * from cache_0 where ckey='23'
將會被收斂為:
select * from cache_{NUM} where ckey=?
IP收斂
如果應(yīng)用依賴的外部服務(wù)眾多且直接使用IP進(jìn)行訪問,將會導(dǎo)致探針采集到大量的外部IP,導(dǎo)致發(fā)散。
收斂邏輯
按照端口對IP進(jìn)行分組。
統(tǒng)計分組后,每個端口內(nèi)包含的IP數(shù),如果超過閾值則收斂。默認(rèn)閾值:50
收斂結(jié)果
{ARMS_IP}:port
支持的數(shù)據(jù)類型
IP
收斂觸發(fā)位置
4.x及以上版本觸發(fā)于探針端
4.x以下版本觸發(fā)于服務(wù)端
支持的探針版本
所有
示例
1.1.1.1:8080
...
1.1.1.255:8080
將被收斂為{ARMS_IP}:8080
。
基數(shù)空間收斂
對于URL類型的維度來說,經(jīng)過上文收斂機制的處理,基本可以解決高基數(shù)問題。但對于SQL等類型來說,即使我們盡可能剔除了可能發(fā)散的信息,依然可能會記錄大量的維度值,為解決這一問題,ARMS對單位時間內(nèi)可以記錄的維度值進(jìn)行了控制,以保證不會出現(xiàn)發(fā)散問題。
收斂邏輯
邏輯較為復(fù)雜,此處僅做簡單介紹。
周期性生成大小固定的基數(shù)空間。
針對每一個維度值,首先判斷基數(shù)空間中是否已存在該值,如存在則原樣返回,否則嘗試放入基數(shù)空間,如果可以放入則原樣返回,否則返回{ARMS_OTHERS}。
收斂結(jié)果
超過空間限制的維度值收斂為{ARMS_OTHERS}。
默認(rèn)閾值
觀測對象 | 閾值(個) |
URL接口 | 每小時500 |
調(diào)度任務(wù) | 每小時1000 |
RPC接口 | 每小時1000 |
上游接口 | 每小時200 |
正常SQL | 每小時100 |
慢SQL | 每小時100 |
外部請求URL | 每小時200 |
外部請求地址 | 每小時100 |
支持的數(shù)據(jù)類型
任意
收斂觸發(fā)位置
4.x及以上版本觸發(fā)于探針端
4.x以下版本觸發(fā)于服務(wù)端
支持的探針版本
所有
示例
指標(biāo)會記錄外部服務(wù)地址,假定外部服務(wù)地址如下,基數(shù)空間的大小為每小時100個記錄。
www.a1.com
www.a2.com
....
www.a1000.com
那么每1小時,僅有前100個外部服務(wù)會被記錄下來,后續(xù)的外部服務(wù)地址都會被收斂為{ARMS_OTHERS}
。
執(zhí)行順序
4.x以下版本
探針端
URL類型
Spring收斂 > 基于內(nèi)存統(tǒng)計的收斂
SQL類型
基于內(nèi)存統(tǒng)計的收斂
IP等其他類型
基于內(nèi)存統(tǒng)計的收斂
服務(wù)端
URL類型
自定義收斂 > 攻擊請求收斂 > 帶參請求收斂 > 靜態(tài)資源收斂 > 無意義單詞收斂 > 智能收斂> 基數(shù)空間收斂
SQL類型
自定義收斂 > 基數(shù)空間收斂
IP等其他類型
自定義收斂 > IP收斂 > 基數(shù)空間收斂
4.x及以上版本
探針端
URL類型
Spring收斂 > 自定義收斂 > 攻擊請求收斂 > 帶參請求收斂 > 靜態(tài)資源收斂 > 無意義單詞收斂 > 智能收斂> 基數(shù)空間收斂
SQL類型
自定義收斂 > SQL規(guī)整化 > 基數(shù)空間收斂
IP等其他類型
自定義收斂 > IP收斂 > 基數(shù)空間收斂
服務(wù)端
不適用
收斂執(zhí)行將按照上述順序逐一執(zhí)行,維度值被任一收斂機制收斂后,將不再繼續(xù)執(zhí)行后續(xù)邏輯。
常見問題
在哪里可以看到收斂前的原始值?
對于4.x以上探針版本,Trace數(shù)據(jù)中會記錄原始的值也會記錄收斂后的值,您可以通過調(diào)用鏈分析功能查看到原始值。更多信息,請參見調(diào)用鏈分析。
對于4.x以下的探針版本,由于大部分收斂邏輯發(fā)生在服務(wù)端,目前無法查看收斂前的原始值。
收斂結(jié)果不滿足預(yù)期,我該如何處理?
可以通過自定義收斂規(guī)則能力進(jìn)行調(diào)整。
打開新版ARMS控制臺,切換到應(yīng)用設(shè)置/收斂配置功能,即可添加自定義收斂規(guī)則。
示例:
添加匹配/api/v1/user/\d+/info
收斂為/api/v1/user/userId/info
,即可將形如/api/v1/user/124343543/info
的請求收斂為/api/v1/user/userId/info
。
收斂結(jié)果誤傷了一些重要接口,我不想這些重要接口被收斂,該如何處理?
參考問題2,打開收斂配置功能,在自定義收斂塊添加排除項即可。
示例:
添加/api/v1/user/9999/info
,那么/api/v1/user/9999/info
就不會被收斂為/api/v1/user/userId/info
。
探針端收斂與服務(wù)端收斂有什么差異?
探針端收斂即意味著收斂行為發(fā)生在探針側(cè),那么上報到服務(wù)端數(shù)據(jù)就已經(jīng)是收斂過的,對于服務(wù)端來說處理的壓力會大大降低,且可以保證100%的數(shù)據(jù)準(zhǔn)確性。
當(dāng)探針版本較低時,很多收斂機制是不支持的,一旦出現(xiàn)了發(fā)散的情況,只能在服務(wù)端進(jìn)行收斂處理,由于探針端并未進(jìn)行收斂處理,此時上報到服務(wù)端的數(shù)據(jù)包可能會很大。一方面存在因數(shù)據(jù)包過大被拒絕導(dǎo)致數(shù)據(jù)丟失的風(fēng)險,另一方面受限于服務(wù)端的處理機制,經(jīng)過收斂處理后的數(shù)據(jù)準(zhǔn)確性會存在一定的偏差。因此,強烈建議升級到最新版本的探針。