鍍金池/ 教程/ Java/ 調(diào)試
定時(shí)任務(wù)
函數(shù)的參數(shù)
超時(shí)
一個(gè) openresty 內(nèi)存“泄漏”問題
獲取 uri 參數(shù)
局部變量
sleep
灰度發(fā)布
TIME_WAIT
代碼覆蓋率
連接池
CentOS 平臺安裝
稀疏數(shù)組
如何只啟動(dòng)一個(gè) timer 工作?
變量的共享范圍
break,return 關(guān)鍵字
Nginx
SQL 注入
如何引用第三方 resty 庫
不同階段共享變量
獲取請求 body
動(dòng)態(tài)生成的 lua-resty-redis 模塊方法
動(dòng)態(tài)加載證書和 OCSP stapling
repeat 控制結(jié)構(gòu)
編碼為 array 還是 object
Nginx 靜態(tài)文件服務(wù)
執(zhí)行階段概念
Lua 函數(shù)
日期時(shí)間函數(shù)
健康監(jiān)測
與其他 location 配合
for 控制結(jié)構(gòu)
函數(shù)定義
HTTPS 時(shí)代
點(diǎn)號與冒號操作符的區(qū)別
String 庫
文件操作
OpenResty 最佳實(shí)踐
<code>ngx.shared.DICT</code> 非隊(duì)列性質(zhì)
使用動(dòng)態(tài) DNS 來完成 HTTP 請求
代碼規(guī)范
什么是 JIT?
Windows 平臺安裝
正確的記錄日志
LuaNginxModule
不用標(biāo)準(zhǔn)庫
C10K 編程
控制結(jié)構(gòu)
請求中斷后的處理
Lua 環(huán)境搭建
Test::Nginx 能指定現(xiàn)成的 nginx.conf,而不是自動(dòng)生成一個(gè)嗎
Lua 基礎(chǔ)數(shù)據(jù)類型
動(dòng)態(tài)限速
PostgresNginxModule
簡單API Server框架
API 測試
location 匹配規(guī)則
虛變量
單元測試
防止 SQL 注入
select + set_keepalive 組合操作引起的數(shù)據(jù)讀寫錯(cuò)誤
阻塞操作
全動(dòng)態(tài)函數(shù)調(diào)用
Web 服務(wù)
典型應(yīng)用場景
Nginx 新手起步
TLS session resumption
輸出響應(yīng)體
調(diào)用代碼前先定義函數(shù)
module 是邪惡的
怎樣理解 cosocket
模塊
Socket 編程發(fā)展
如何對 Nginx Lua module 添加新 api
如何在后臺開啟輕量級線程完成定時(shí)任務(wù)?
如何定位問題
table 庫
json 解析的異常捕獲
如何安裝火焰圖生成工具
lua 中如何 continue
if 是邪惡的
為什么我們的域名不能被解析
抵制使用 module() 定義模塊
測試
body 在 location 中的傳遞
Lua 入門
子查詢
pipeline 壓縮請求數(shù)量
如何發(fā)起新 HTTP 請求
Lua 簡介
緩存失效風(fēng)暴
Ubuntu 平臺安裝
日志輸出
緩存
Lua 面向?qū)ο缶幊?/span>
Nginx 陷阱和常見錯(cuò)誤
Redis 接口的二次封裝(發(fā)布訂閱)
日志
訪問有授權(quán)驗(yàn)證的 Redis
正則表達(dá)式
lock
熱裝載代碼
調(diào)用 FFI 出現(xiàn) &quot;table overflow&quot;
數(shù)據(jù)合法性檢測
禁止某些終端訪問
控制結(jié)構(gòu) if-else
調(diào)試
與 Docker 使用的網(wǎng)絡(luò)瓶頸
PostgresNginxModule 模塊的調(diào)用方式
用 do-end 整理你的代碼
FFI
什么時(shí)候使用
簡介
環(huán)境搭建
Mac OS X 平臺安裝
火焰圖
負(fù)載均衡
while 型控制結(jié)構(gòu)
如何定位 openresty 崩潰 bug
使用 Nginx 內(nèi)置綁定變量
判斷數(shù)組大小
請求返回后繼續(xù)執(zhí)行
Redis 接口的二次封裝
KeepAlive
反向代理
協(xié)議無痛升級
數(shù)學(xué)庫
元表
Vanilla 介紹
HelloWorld
LuaCjsonLibrary
持續(xù)集成
代碼靜態(tài)分析
網(wǎng)上有大量對 Lua 調(diào)優(yōu)的推薦,我們應(yīng)該如何看待?
script 壓縮復(fù)雜請求
非空判斷
性能測試
函數(shù)返回值
API 的設(shè)計(jì)
kong 介紹
表達(dá)式
不支持事務(wù)
LuaRestyDNSLibrary 簡介

調(diào)試

調(diào)試是一個(gè)程序猿非常重要的能力,人寫的程序總會(huì)有 bug,所以需要 debug。如何方便和快速的定位 bug,是我們討論的重點(diǎn),只要 bug 能定位,解決就不是問題。

對于熟悉用 Visual Studio 和 Eclipse 這些強(qiáng)大的集成開發(fā)環(huán)境的來做 C++ 和 Java 的同學(xué)來說,OpenResty 的 debug 要原始很多,但是對于習(xí)慣 Python 開發(fā)的同學(xué)來說,又是那么的熟悉。 張銀奎有本《軟件調(diào)試》的書,windows 客戶端程序猿應(yīng)該都看過,大家可以去試讀下,看看里面有多復(fù)雜:(

對于 OpenResty,壞消息是,沒有單步調(diào)試這些玩意兒(我們嘗試搞出來過 ngx Lua 的單步調(diào)試,但是沒人用...); 好消息是,它像 Python 一樣,非常簡單,不用復(fù)雜的技術(shù),只靠 print 和 log 就能定位絕大部分問題,難題有火焰圖這個(gè)神器。

  • 關(guān)閉 code cache

在調(diào)試的時(shí)候最好關(guān)閉 lua_code_cache 這個(gè)選項(xiàng)。

lua_code_cache off;

關(guān)閉 lua_code_cache 之后,OpenResty 會(huì)給每個(gè)請求創(chuàng)建新的 Lua VM。由于沒有 Lua module 的緩存,新的 VM 會(huì)去加載剛最新的 Lua 文件。 這樣,你修改完代碼后,不用 reload Nginx 就可以生效了。在生產(chǎn)環(huán)境下記得打開這個(gè)選項(xiàng)。

當(dāng)然,由于每個(gè)請求運(yùn)行在獨(dú)立的 Lua VM 里,lua_code_cache off 會(huì)帶來以下幾個(gè)問題:

  1. 每個(gè)請求都會(huì)有獨(dú)立的 module,獨(dú)立的 lrucache,獨(dú)立的 timer,獨(dú)立的線程池。
  2. 跟請求無關(guān)的模塊,由于不會(huì)被新的請求加載,并不會(huì)主動(dòng)更新。比如 init_by_lua_file 引用的文件就不會(huì)被更新。
  3. *_by_lua_block 里面的代碼,由于不在 Lua 文件里面,設(shè)置 lua_code_cache 對其沒有意義。

如果調(diào)試的目標(biāo)涉及以上內(nèi)容,仍需設(shè)置 lua_code_cache on,通過 reload 來更新代碼。

  • 記錄日志

這個(gè)看上去誰都會(huì)的東西,要想做好也不容易。

你有遇到這樣的情況嗎?QA 發(fā)現(xiàn)了一個(gè) bug,開發(fā)說我修改代碼加個(gè)日志看看,然后 QA 重現(xiàn)這個(gè)問題,發(fā)現(xiàn)日志不夠詳細(xì),需要再加,反復(fù)幾次,然后再給 QA 一個(gè)沒有日志的版本,繼續(xù)測試其他功能。

如果產(chǎn)品已經(jīng)發(fā)布到用戶那里了呢?如果用戶那里是隔離網(wǎng),不能遠(yuǎn)程怎么辦?

你在寫代碼的時(shí)候,就需要考慮到調(diào)試日志。 比如這個(gè)代碼:

local response, err = redis_op.finish_client_task(client_mid, task_id)
if response then
    put_job(client_mid, result)
    ngx.log(ngx.WARN, "put job:", common.json_encode({channel="task_status", mid=client_mid, data=result}))
end

我們在做一個(gè)操作后,就把結(jié)果記錄到 Nginx 的 error.log 里面,等級是 warn。在生產(chǎn)環(huán)境下,日志等級默認(rèn)為 error,在我們需要詳細(xì)日志的時(shí)候,把等級調(diào)整為 warn 即可。在我們的實(shí)際使用中,我們會(huì)把一些很少發(fā)生的重要事件,做為 error 級別記錄下來,即使它并不是 Nginx 的錯(cuò)誤。

與日志配套的,你需要logrotate來做日志的切分和備份。