前言
1.減少開銷–減少向redis服務器的請求次數
2.原子操作–redis將lua腳本作為一個原子執行
3.可復用–其他客戶端可以使用已經執行過的lua腳本
4.增加redis靈活性–lua腳本可以幫助redis做更多的事情
lua腳本本身體積小,啟動速度快.
因此,從redis 2.6.0開始,redis在服務器端內置lua解釋器,下面話不多說了,來開始本文的正文:
最近在配合移動端調試的時候,被抓去debug一個在清除redis緩存之后才會出現的網關錯誤。于是打開服務器上的log定位到類似錯誤:
[error] 7#7: *12030 lua entry thread aborted: runtime error: /data/share/apps/lua/access_check.lua:133: bad argument #1 to 'decode' (string expected, got userdata)
該段代碼的主要作用是在openresty中lua讀取redis中數據并解碼為json:
1
2
3
4
5
6
7
8
|
local access_token = redis_client:read_by_key(token_key) if access_token == nil then -- do something... return false end local obj_token = cjson.decode(access_token) -- do something |
通過查詢資料得知原因:lua讀取redis數據返回結果為空時,返回的結果不是nil而是userdata類型的ngx.null。
因為nil在lua中有特殊的意義,如果一個變量被設置為nil相當于告知該變量未定義(不存在)一樣,如果把redis查詢的結果為空設置為nil,而該查詢的key對應在redis中又是存在的,就無法把查詢為空和未定義區分開來了,這樣顯然是不合理的。所以必須使用一個userdata類型的值來表示這個查詢記錄為空,但是又不等同于未定義變量(ngx.null)。
因此,代碼做如下修改即可:
1
2
3
4
5
6
7
8
|
local access_token = redis_client:read_by_key(token_key) if access_token == ngx. null or access_token == nil then -- do something... return false end local obj_token = cjson.decode(access_token) -- do something |
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:https://notes.doublemine.me/2018-01-26-lua讀取redis數據的null判斷.html