openresty通過lua增加隨機traceid
在沒有引入zipkin(或者阿里的鷹眼,百度的華佗)這種trace系統的時候,排查問題的一般思路都是按照請求鏈路來尋找問題源。因此如果能在請求鏈路中有一個唯一的標識就最好了,而在nginx/openresty做接入層的架構中,可以通過lua指令碼生成一個隨機traceid。
隨機數的生成原理,都是先初始化一個隨機數種子,由於偽隨機數的特性,種子的隨機性就顯得格外重要,而一般種子的生成都是通過時間的倒序來選取
lua 隨機數生成方法
首先我們看下通常lua的隨機數生成方法
math.randomseed(tonumber(tostring(os.time()):reverse():sub(1,6)))
math.random(m,n)
通過時間字串的逆序初始化隨機種子,這裡注意到有個sub
函式做了截斷,是因為
math.randomseed
will call the underlying C functionsrand
which takes an unsigned integer valueLua will cast the value of the seed to this format. In case of an overflow the seed will actually become a bad seed, without warning
所以需要避免出現高型別向低型別轉換的溢位問題
common 方法的問題
但上面的方法有個問題,就是os.time()
函式返回的是秒(10位整數), 所以在做web請求的traceid時很容易就出現重複,影響問題追蹤的效率,而lua如果要以毫秒為單位的時間來初始化隨機種子,需要引入socket等外部模組,對於openresty來說一般都是封裝好的,不方便去做這種定製
利用openresty 與lua生成traceid
幸運的是,nginx-lua中有個函式ngx.now
會返回一個浮點數(當然在lua中統一為number型別),3位小數即為毫秒位,所以問題就變得簡單了
access_by_lua_block {
math.randomseed(tonumber(tostring(ngx.now()*1000):reverse():sub(1,9)))
local randvar = string.format("%.0f",math.random(1000000000000000000,9223372036854775807))
ngx.req.set_header("traceid", randvar)
}
通過ngx.now()*1000
拿到毫秒資料轉換為字串取反,這樣毫秒資料的變化才能顯出效果; unsigned int(64bit機器下為4byte) 最大值為10位數,我們取前9位避免資料溢位帶來的轉換問題; lua在顯示大於64bit的資料時會自動用科學技術法表示,所以我們需要通過string.format函式來將其轉換為19位數字,然後通過ngx.req.set_header新增到請求頭中去
相關文章
- openresty及lua的隨機函式REST隨機函式
- OpenResty + Lua 動態增加 Zuul 節點RESTZuul
- 安裝lua和openrestyREST
- openresty使用lua操作mysqlRESTMySql
- 日誌追蹤:log增加traceId
- Lua OpenResty容器化(考古歷程)REST
- 【Nginx】Openresty增加waf配置NginxREST
- OpenResty debugger: lua-resty-replREST
- OpenResty+lua+redis+mysql多級快取RESTRedisMySql快取
- nginx+lua(OpenResty),實現訪問限制NginxREST
- openresty+redis配合 lua指令碼封停 IPRESTRedis指令碼
- 使用Lua和OpenResty搭建驗證碼伺服器REST伺服器
- nginx-通過lua動態更改upstreamNginx
- 使用 Nginx + Lua(OpenResty)開發高效能Web應用NginxRESTWeb
- 用 Nginx + Lua(OpenResty) 開發高效能 Web 應用NginxRESTWeb
- 隨機過程(高斯隨機過程、譜分析、白噪聲)隨機
- [lua][openresty]程式碼覆蓋率檢測的解決方式REST
- cetnos7下openresty使用luarocks 進行lua的包管理REST
- 在 OpenResty 裡實現程式間通訊REST
- rpm安裝的php 通過編譯增加模組PHP編譯
- (轉)Oracle的隨機數、隨機日期和時間、隨機字串及造資料匿名過程Oracle隨機字串
- 隨機過程複習筆記隨機筆記
- 編譯安裝基於nginx與lua的高效能web平臺-openresty編譯NginxWebREST
- SpringBoot(18)---通過Lua指令碼批量插入資料到Redis布隆過濾器Spring Boot指令碼Redis過濾器
- 透過例子學習Lua(2)---Lua流程控制(轉)
- 一次「找回」TraceId的問題分析與過程思考
- OpenRestyREST
- 關於OpenResty中使用lua-resty-jwt出現的一個異常symbol not foundRESTJWTSymbol
- 給ubuntu虛機增加一個磁碟的過程Ubuntu
- 透過例子學習Lua(3)----Lua資料結構(轉)資料結構
- 隨機生成指定面積單連通區域隨機
- 透過鉤子函式+Traceid實現Flask鏈路追蹤函式Flask
- 通過跳板機連線MySQLMySql
- 通過USB埠 SSH 到手機
- 透過例子學習Lua(5)--Lua與C的互動(轉)
- 隨機過程學習筆記——概論隨機筆記
- SQL學習-隨機數,儲存過程SQL隨機儲存過程
- 隨機之美,隨機森林隨機森林