av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

Openresty的開發(fā)閉環(huán)初探

1. 為什么值得入手?

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、微信小程序定制開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了沙坡頭免費(fèi)建站歡迎大家使用!

Nginx 作為現(xiàn)在使用最廣泛的高性能后端服務(wù)器,Openresty 為之提供了動(dòng)態(tài)預(yù)言的靈活,當(dāng)性能與靈活走在了一起,無疑對(duì)于被之前陷于臃腫架構(gòu),苦于提升性能的工程師來說是重大的利好消息,本文就是在這種背景下,將初入這一未知的領(lǐng)域之后的一些經(jīng)驗(yàn)與大家分享一下,若有失言之處,歡迎指教。

2. 安裝

現(xiàn)在除了能在 [Download](http://openresty.org/en/download.html )里面下載源碼來自己編譯安裝,現(xiàn)在連預(yù)編譯好的[包](http://openresty.org/en/linux-packages.html)都有了, 安裝也就分分鐘的事了。

3. hello world

/path/to/nginx.conf`, `conftent_by_lua_file 里面的路徑請(qǐng)根據(jù) lua_package_path 調(diào)整一下。

 
 
  1. ``` 
  2.    location / { 
  3.        content_by_lua_file ../luablib/hello_world.lua; 
  4.    } 
  5.    ``` 
  6.  
  7. /path/to/openresty/lualib/hello_world.lua` 
  8.    ``` 
  9.    ngx.say("Hello World") 
  10.    ``` 

訪問一下, Hello World~.

 
 
  1. ``` 
  2.   HTTP/1.1 200 OK 
  3.   Connection: keep-alive 
  4.   Content-Type: application/octet-stream 
  5.   Date: Wed, 11 Jan 2017 07:52:15 GMT 
  6.   Server: openresty/1.11.2.2 
  7.   Transfer-Encoding: chunked 
  8.   Hello World 
  9.   ``` 

基本上早期的 Openresty 相關(guān)的開發(fā)的路數(shù)也就大抵如此了, 將 lua 庫(kù)發(fā)布到 lualib 之下,將對(duì)應(yīng)的 nginx 的配置文件發(fā)布到 nginx/conf 底下,然后 reload 已有的 Openresty 進(jìn)程(少數(shù)需要清空 Openresty shared_dict 數(shù)據(jù)的情況需要重啟 )。

如果是測(cè)試環(huán)境的話,那更是簡(jiǎn)單了,在 http 段將 lua_code_cache 設(shè)為 off , Openresty 不會(huì)緩存 lua 腳本,每次執(zhí)行都會(huì)去磁盤上讀取 lua 腳本文件的內(nèi)容,發(fā)布之后就可以直接看效果了(當(dāng)然如果配置文件修改了,reload 是免不了了)。是不是找到一點(diǎn)當(dāng)初 apache 寫 php 的感覺呢:)

4. 開發(fā)語言 Lua 的大致介紹

環(huán)境搭建完畢之后,接下來就是各種試錯(cuò)了。關(guān)于 Lua 的介紹,網(wǎng)上的資料比如:Openresty ***實(shí)踐(版本比較多,這里就不放了)寫的都會(huì)比較詳細(xì),本文就不在這里過多解釋了,只展示部分基礎(chǔ)的Lua的模樣。

下面對(duì) lua 一些個(gè)性有趣的地方做一下分享,可能不會(huì)涉及到 lua 語言比較全面或者細(xì)節(jié)的一些部分,作為補(bǔ)充,讀者可以翻閱官方的< >。

 
 
  1. ```lua 
  2.    -- 單行注釋以兩個(gè)連字符開頭 
  3.    --[[ 
  4. 行注釋 
  5.    --]] 
  6.    -- 變量賦值 
  7.    num = 13  -- 所有的數(shù)字都是雙精度浮點(diǎn)型。 
  8.    s = '單引號(hào)字符串' 
  9.    t = "也可以用雙引號(hào)" 
  10.    u = [[ 多行的字符串 
  11.           ]] 
  12.    -- 控制流程,和python最明顯的差別可能就是冒號(hào)變成了do, ***還得數(shù)end的對(duì)應(yīng) 
  13.    -- while 
  14.    while n < 10 do 
  15.      nn = n + 1  -- 不支持 ++ 或 += 運(yùn)算符。 
  16.    end 
  17.    -- for 
  18.    for i = 0, 9 do 
  19.      print(i) 
  20.    end 
  21.    -- if語句: 
  22.    f n == 0 then 
  23.      print("no hits") 
  24.    elseif n == 1 then 
  25.      print("one hit") 
  26.    else 
  27.      print(n .. " hits") 
  28.    end 
  29.    --只有nil和false為假; 0和 ''均為真! 
  30.    if not aBoolValue then print('false') end 
  31.    -- 循環(huán)的另一種結(jié)構(gòu): 
  32.    repeat 
  33.      print('the way of the future') 
  34.      numnum = num - 1 
  35.    until num == 0 
  36.    -- 函數(shù)定義: 
  37.    function add(x, y) 
  38.      return x + y 
  39.    end 
  40.    -- table 用作鍵值對(duì) 
  41.    t = {key1 = 'value1', key2 = false} 
  42.    print(t.key1)  -- 打印 'value1'. 
  43.    -- 使用任何非nil的值作為key: 
  44.    u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'} 
  45.    print(u[6.28])  -- 打印 "tau" 
  46.    -- table用作列表、數(shù)組 
  47.    v = {'value1', 'value2', 1.21, 'gigawatts'} 
  48.    for i = 1, #v do  -- #v 是列表的大小 
  49.      print(v[i]) 
  50.    end 
  51.    -- 元表 
  52.    f1 = {a = 1, b = 2}  -- 表示一個(gè)分?jǐn)?shù) a/b. 
  53.    f2 = {a = 2, b = 3} 
  54.    -- 這會(huì)失?。?nbsp;
  55.    -- s = f1 + f2 
  56.    metafraction = {} 
  57.    function metafraction.__add(f1, f2) 
  58.      local sum = {} 
  59.      sum.b = f1.b * f2.b 
  60.      sum.a = f1.a * f2.b + f2.a * f1.b 
  61.      return sum 
  62.    end 
  63.    setmetatable(f1, metafraction) 
  64.    setmetatable(f2, metafraction) 
  65.    s = f1 + f2  -- 調(diào)用在f1的元表上的__add(f1, f2) 方法 
  66.    -- __index、__add等的值,被稱為元方法。 
  67.    -- 這里是一個(gè)table元方法的清單: 
  68.    -- __add(a, b)                     for a + b 
  69.    -- __sub(a, b)                     for a - b 
  70.    -- __mul(a, b)                     for a * b 
  71.    -- __div(a, b)                     for a / b 
  72.    -- __mod(a, b)                     for a % b 
  73.    -- __pow(a, b)                     for a ^ b 
  74.    -- __unm(a)                        for -a 
  75.    -- __concat(a, b)                  for a .. b 
  76.    -- __len(a)                        for #a 
  77.    -- __eq(a, b)                      for a == b 
  78.    -- __lt(a, b)                      for a < b 
  79.    -- __le(a, b)                      for a <= b 
  80.    -- __index(a, b)    for a.b 
  81.    -- __newindex(a, b, c)             for a.b = c 
  82.    -- __call(a, ...)                  for a(...) 
  83.    ``` 

以上參考了

[learn lua in y minute](https://learnxinyminutes.com/docs/zh-cn/lua-cn/ ) ,做了適當(dāng)?shù)牟眉魜碜稣f明。

4.1 Lua 語言個(gè)性的一面

4.1.1 ***道墻: 打印 table

作為 lua 里面唯一標(biāo)準(zhǔn)的數(shù)據(jù)結(jié)構(gòu), 直接打印居然只有一個(gè) id 狀的東西,這里說這一點(diǎn)沒有抱怨的意思,只是讓讀者做好倒騰的心理準(zhǔn)備,畢竟倒騰一個(gè)簡(jiǎn)潔語言終歸是有代價(jià)的。

了解決定背后的原因,有時(shí)候比現(xiàn)成的一步到位的現(xiàn)成方案這也是倒騰的另一面好處吧,這里給出社區(qū)里面的[討論](http://luausers.org/wiki/TableSerialization)

舉個(gè)例子:

lua 里面一般使用 #table 來獲取 table 的長(zhǎng)度,究其原因,lua 對(duì)于未定義的變量、table 的鍵,總是返回 nil,而不像 python 里面肯定是拋出異常, 所以 # 來計(jì)算 table 長(zhǎng)度的時(shí)候只會(huì)遍歷到***個(gè)值為 nil 的地方,畢竟他不能一直嘗試下去,這時(shí)候就需要使用 table.maxn 的方式來獲取了。

4.1.2 Good or Bad ? 自動(dòng)類型轉(zhuǎn)換

如果你在 python 里面去把一個(gè)字符串和數(shù)字相加,python 必定以異?;貞?yīng)。

 
 
  1. ```python 
  2. >>> "a" + 1 
  3. Traceback (most recent call last): 
  4.   File "", line 1, in  
  5. TypeError: cannot concatenate 'str' and 'int' objects 
  6. ``` 

但是 Lua 覺得他能搞定。

 
 
  1. ```lua 
  2. > = "20" + 10 
  3. 30 
  4. ``` 

如果你覺得 Lua 選擇轉(zhuǎn)換加號(hào)操作符的操作數(shù)成數(shù)字類型去進(jìn)行求值顯得不可思議的,下面這種情況下,這種轉(zhuǎn)換又貌似是可以有點(diǎn)用的了 print("hello" .. 123) ,這時(shí)你不用手動(dòng)去將所有參數(shù)手工轉(zhuǎn)換成字符串類型。

尚沒有定論說這項(xiàng)特性就是一無是處,但是這種依賴語言本身不明顯的特性的代碼筆者是不希望在項(xiàng)目里面去踩雷的。

4.1.3 多返回值

Lua 開始變得越來越與眾不同了:允許函數(shù)返回多個(gè)結(jié)果。

 
 
  1. ``` 
  2.     function foo0() end --無返回值 
  3.     function foo1() return 'a' end -- 返回一個(gè)結(jié)果 
  4.     function foo2() return 'a','b' end -- 返回兩個(gè)結(jié)果 
  5.     -- 多重賦值時(shí), 函數(shù)調(diào)用是***一個(gè)表達(dá)式時(shí) 
  6.     -- 保留盡可能多的返回值 
  7.     x, y = foo2()     -- x='a', y='b' 
  8.     x = foo2()        -- x='a', 'b'被丟棄 
  9.     x,y,z = 10,foo2()    -- x=10, y='a', z='b' 
  10.     -- 如果多重賦值時(shí),函數(shù)調(diào)用不是***一個(gè)表達(dá)式時(shí) 
  11.     -- 只產(chǎn)生一個(gè)值 
  12.     x, y = foo2(),20   -- x='a', y=20    
  13.     x,y = foo0(), 20, 30 -- x=nil, y= 20,30被丟棄,這種情況當(dāng)函數(shù)沒有返回值時(shí),會(huì)用nil來補(bǔ)充。 
  14.     x,y,z = foo2() -- x='a', y='b', z=nil, 這種情況函數(shù)沒有足夠的返回值時(shí)也會(huì)用nil來補(bǔ)充。 
  15.     -- 同樣在函數(shù)調(diào)用、table聲明中 函數(shù)調(diào)用作為***的表達(dá)式,都會(huì)竟可能多的填充返回值,如果不是***,則只返回一個(gè) 
  16.     print(foo2(), 1)    --> a  1 
  17.     print(1, foo2())    --> 1  a  b 
  18.     t = {foo2(), 1}     --> {'a', 1} 
  19.     t = {1, foo2()}     --> {1, 'a', 'b'} 
  20.     -- 阻止這種參數(shù)順序搞事: 
  21.     print(1, (foo2())) -- 1 a 加一層括號(hào),強(qiáng)制只返回一個(gè)值 
  22.     ``` 

4.1.4 真?zhèn)€性: 模式匹配

簡(jiǎn)潔的 Lua 容不下行數(shù)比自己實(shí)現(xiàn)語言行數(shù)還多的正則表達(dá)式實(shí)現(xiàn)(無論是 POSIX ,還是 Perl 正則表達(dá)式),于是乎有了獨(dú)樹一幟的模式與匹配,下面只用模式匹配來做 URL 解碼、編碼功能實(shí)現(xiàn)的演示。

 
 
  1. ``` 
  2.   -- 解碼 
  3.   function unescape(s) 
  4.     s = string.gsub(s, "+", " ") 
  5.     s = string.gsub(s, "%%(%x%x)", function (h) 
  6.           return string.char(tonumber(h, 16)) 
  7.         end) 
  8.     return s   
  9.   end 
  10.   print(unescape("a%2Bb+%3D+c")) ---> a+b =c 
  11.   cgi = {} 
  12.   function decode(s) 
  13.     for name,value in string.gmatch(s, "([^&=]+)=([^&=]+)") do 
  14.       name = unescape(name) 
  15.       value = unescape(value) 
  16.       cgi[name] = value 
  17.     end 
  18.   end 
  19.   -- 編碼 
  20.   function escape(s) 
  21.     s = string.gsub(s, "[&=+%%%c]", function(c) 
  22.         return string.format("%%%02X", string.byte(c)) 
  23.       end) 
  24.     s = string.gsub(s, " ", "+") 
  25.     return s 
  26.   end   
  27.   function encode(t) 
  28.     local b = {} 
  29.     for k,v in pairs(t) do 
  30.       b[#b+1] = (escape(k) .. "=" .. escape(v)) 
  31.     end 
  32.     return table.concat(b,'&') 
  33.   end 
  34.   ``` 

模式匹配實(shí)現(xiàn)的功能是足夠強(qiáng)大,但是工程上是否值得投入還值得商榷,沒有通用性,只此 lua 一家用。

雖然正則表達(dá)式也是不好調(diào)試,但是至少知道了解的人多,可能到***筆者也不會(huì)多深入 lua 的模式匹配,但是如此單純?yōu)榱藴p少代碼而放棄正則表達(dá)式現(xiàn)成的庫(kù),自己又玩了一套,這也是沒誰了。

4.1.5 與 c 的天然親密

一言不合,就拿 c 寫一個(gè)庫(kù)給 lua 用,由此可見兩門語言是多么哥倆好了。如果舉個(gè)例子的話就是 lua5.1 里面的位操作符,luajit 就是這樣提供的解決方案 [Lua Bit Operations Module](http://bitop.luajit.org ),有興趣的讀者可以下載源碼看一下,完全就是用 lua 的 c api 包裝了 c 里面的位操作符出來用。

除了加了些限制的話(ex. 位移出來的必然是 32 位有符)。lua 除了數(shù)據(jù)結(jié)構(gòu)上面的過于簡(jiǎn)潔外,其他的控制結(jié)構(gòu)、操作符這些語言特性基本該有的都有了,唯獨(dú)缺了位操作符。

5.1 為什么當(dāng)時(shí)選擇了不實(shí)現(xiàn)位操作符呢?有知道出處或者原因的讀者歡迎留言告知。(順帶一提,lua5.2 里面有官方的 bit32 庫(kù)可以用,lua5.3 已經(jīng)補(bǔ)上了位操作符,另外 Openresty 在 lua 版本的選擇上是選擇停留在 5.1,這點(diǎn)在 github 的 Issue 里面有回答過,且沒有升級(jí)的打算)。

4.1.6 雜

  • 只有 nil 、false 為布爾假。
  • lua 中的索引習(xí)慣以 1 開始。
  • 沒有整型,所有數(shù)字都是浮點(diǎn)數(shù)。
  • 當(dāng)函數(shù)的參數(shù)是單引號(hào)或者雙引號(hào)的字符串或者 table 定義的時(shí)候,可以省略外面的 () , 所以 require "cookie" 并不是代表 require 是個(gè)關(guān)鍵字。
  • table[index] 等價(jià)于 table [index] 。

5. 構(gòu)建公司層面完整的 Openresty 生態(tài)

5.1 開發(fā)助手:成長(zhǎng)中的 resty 命令

習(xí)慣了動(dòng)態(tài)語言的解釋器的立即反饋,哪怕是熟悉 lua 的同學(xué),初入 Openresty 的時(shí)候似乎又想起了編譯->執(zhí)行->修改的***循環(huán)的記憶,因?yàn)槊看味夹枰薷呐渲梦募?、reload 、測(cè)試再如此重復(fù)個(gè)幾次才能寫對(duì)一段函數(shù),resty 命令無疑期待,筆者也希望 resty 命令能夠更加完善、易用。

另外提一個(gè)小遺憾,現(xiàn)在 resty 命令不能玩 Openresty 里面的 shared_dict 共享內(nèi)存, 這可能跟目前 resty 使用的 nginx 配置的模板是固定有關(guān)吧。

5.2 環(huán)境:可能不再需要重新編譯 Nginx

有過 Nginx 維護(hù)開發(fā)經(jīng)驗(yàn)的同學(xué)可能都熟悉這么一個(gè)過程,因?yàn)槎喟霑?huì)做業(yè)務(wù)的拆分,除了小公司外,基本都不會(huì)把一個(gè) Nginx 的所有可選模塊都編譯進(jìn)去,每次有新的 Nginx 相關(guān)的功能的增減,都免不了重新編譯,重新部署上線。

Openresty 是基于 Nginx 的,如果是新增 Nginx 本身的功能,重新編譯增加功能沒什么好說的,如何優(yōu)雅的更新 Nginx 服務(wù)進(jìn)程,Nginx 有提供方案、各家也有各家的服務(wù)可靠性要求,具體怎么辦這里就不贅述了。

5.3 發(fā)布部署

Openresty 本身的發(fā)布部署跟 Nginx 本身沒有太大的不同,Openresty 本身的發(fā)布部署官方也推出了 linux 平臺(tái)的預(yù)編譯好的包,在這樣的基礎(chǔ)上構(gòu)建環(huán)境就更加便捷。

環(huán)境之上,首先是 lua 腳本和 nginx 配置文件的發(fā)布,在版本管理之下,加上自動(dòng)構(gòu)建的發(fā)布平臺(tái),Openresty 的應(yīng)用分分鐘就可以上線了:)

這個(gè)流程本身無關(guān) Openresty ,但是簡(jiǎn)而言之一句話,當(dāng)重復(fù)性的東西自動(dòng)化之后,我們才有精力去解決更有趣的問題,不是么?

5.4 第三方庫(kù)的安裝、管理

(1)以前:自己找個(gè)第三方庫(kù)編譯之后扔到 Openresty 的 lualib 目錄,luajit 是否兼容、是否 lua5.1 兼容都得自己來測(cè)試一遍。

(2)之前:對(duì)于解決前一個(gè)問題,Openresty 是通過給出 lua 里面 Luarocks 的安裝使用來解決的,但是這種方式不能解決上面所說的第二個(gè)問題,所以現(xiàn)在這種方式已經(jīng)不推薦使用了,下面貼一下官網(wǎng)的說明,只做內(nèi)容收集、展示用, ***的具體說明參見[using luarocks](http://openresty.org/en/using-luarocks.html)。

 
 
  1. ``` 
  2. wget http://luarocks.org/releases/luarocks-2.0.13.tar.gz 
  3. tar -xzvf luarocks-2.0.13.tar.gz 
  4. cd luarocks-2.0.13/ 
  5. ./configure --prefix=/usr/local/openresty/luajit \ 
  6.     --with-lua=/usr/local/openresty/luajit/ \ 
  7.     --lua-suffix=jit \ 
  8.     --with-lua-include=/usr/local/openresty/luajit/include/luajit-2.1 
  9. make 
  10. sudo make install 
  11. ``` 

安裝第三方庫(kù)示例:

 
 
  1. sudo /usr/local/openresty/luajit/luarocks install md5。 

(3)現(xiàn)在:Openresty 提供了解決這兩個(gè)問題的完整方案,自己的包管理的規(guī)范和倉(cāng)庫(kù)[opm](https://opm.openresty.org/)。

詳細(xì)的標(biāo)準(zhǔn)說明, 請(qǐng)移步:https://github.com/openresty/opm#readme, 這里就不多做介紹了。

關(guān)于第三方庫(kù)的質(zhì)量,Openresty 官網(wǎng)上也有了專門的[QA頁面](http://qa.openresty.org/),至少保證了第三方庫(kù)一些實(shí)現(xiàn)的下限,不像 python 里面安裝某些第三方包,比如 aerospike 的,里面安裝 python 客戶端,每次要去網(wǎng)上拉個(gè) c 的客戶端下來之類的稀奇古怪的玩法,期待 opm 未來更加完善。

5.5 關(guān)于單元測(cè)試

關(guān)于自動(dòng)化測(cè)試的話,就筆者的試用經(jīng)驗(yàn)而言,感覺還不是特別的順手,官方提供的 Test:Nginx 工具已經(jīng)提供簡(jiǎn)潔強(qiáng)大的功能,但是如果作為 TDD 開發(fā)中的測(cè)試驅(qū)動(dòng)的工具而言,筆者覺得報(bào)錯(cuò)信息的有效性上面可能是唯一讓人有點(diǎn)覺得有點(diǎn)捉雞的地方,尚不清楚是否是筆者用的有誤——

一般 Test:Nginx 的報(bào)錯(cuò)多半無法幫助調(diào)試代碼,還是要走調(diào)試、修改的老路子。但是 Test:Nginx 的真正價(jià)值筆者覺得是講實(shí)例代碼和測(cè)試***的結(jié)合,由此養(yǎng)成了看每個(gè) Openresty 相關(guān)的項(xiàng)目代碼都必先閱讀里面的 Test:Nginx 的測(cè)試,當(dāng)然最多最豐富的還是 Openresty 本身的測(cè)試。

舉個(gè)實(shí)際的例子:

在使用 Test:Nginx 之前,之前對(duì)于 Nginx 的日志輸出,一切的測(cè)試依據(jù),對(duì)于外面的運(yùn)行環(huán)境跑的測(cè)試只能通過 http 的請(qǐng)求和返回來做測(cè)試的判斷條件,這時(shí)候?qū)τ谝恍┣闆r就束手無策了, 比如處理某種錯(cuò)誤情況可能需要在 log 里面記錄一下,這種測(cè)試就無法保證。

另外也有類似[lua-resty-test](https://github.com/membphis/lua-resty-test)這樣通過提供組件的方式來進(jìn)行,但是我們一旦接觸的了 Test:Nginx 的測(cè)試方法之后,這些就顯得相形見絀了,我們舉個(gè)實(shí)際的例子。

 
 
  1. ``` 
  2.    # vim:set ft= ts=4 sw=4 et fdm=marker: 
  3.    use Test::Nginx::Socket::Lua; 
  4.    #worker_connections(1014); 
  5.    #master_process_enabled(1); 
  6.    #log_level('warn'); 
  7.    #repeat_each(2); 
  8.    plan tests => repeat_each() * (blocks() * 3 + 0); 
  9.    #no_diff(); 
  10.    no_long_string(); 
  11.    #master_on(); 
  12.    #workers(2); 
  13.    run_tests(); 
  14.    __DATA__ 
  15.    === TEST 1: lpush & lpop 
  16.    --- http_config 
  17.        lua_shared_dict dogs 1m; 
  18.    --- config 
  19.        location = /test { 
  20.            content_by_lua_block { 
  21.                local dogs = ngx.shared.dogs 
  22.                local len, err = dogs:lpush("foo", "bar") 
  23.                if len then 
  24.                    ngx.say("push success") 
  25.                else 
  26.                    ngx.say("push err: ", err) 
  27.                end 
  28.                local val, err = dogs:llen("foo") 
  29.                ngx.say(val, " ", err) 
  30.                local val, err = dogs:lpop("foo") 
  31.                ngx.say(val, " ", err) 
  32.                local val, err = dogs:llen("foo") 
  33.                ngx.say(val, " ", err) 
  34.                local val, err = dogs:lpop("foo") 
  35.                ngx.say(val, " ", err) 
  36.            } 
  37.        } 
  38.    --- request 
  39.    GET /test 
  40.    --- response_body 
  41.    push success 
  42.    1 nil 
  43.    bar nil 
  44.    0 nil 
  45.    nil nil 
  46.    --- no_error_log 
  47.    [error] 
  48.    ``` 

以上是隨便選取的lua-nginx-module的測(cè)試文件145-shdict-list.t中的一段做說明,測(cè)試文件分為3個(gè)部分:

  • __DATA__以上的部分編排測(cè)試如何運(yùn)行,
  • __DATA__作為分隔符,
  • __DATA__以下的是各個(gè)測(cè)試的說明部分。

測(cè)試部分如果具體細(xì)分的話,

  • 一般由 ====TEST 1: name 開始到下一個(gè)測(cè)試的聲明;
  • 然后是配置 nginx 配置的 http_config、config、... 的部分;
  • 接著是模擬請(qǐng)求的部分,基本就是 http 請(qǐng)求報(bào)文的設(shè)定,功能不限于這里的 request 部分;
  • ***是輸出部分,這時(shí)候不僅是 http 報(bào)文的 body 部分之類的 http 響應(yīng)、還有 nginx 的日志的輸出這樣的測(cè)試條件。

對(duì)于這樣清晰可讀、還能順帶把使用例子寫的清楚的單元測(cè)試的框架, pythoner 真的難道不羨慕么?

5.6 關(guān)于調(diào)試、性能調(diào)優(yōu)

這一塊筆者還沒有深入研究過,所以這里就不多說了,這里就做一下相關(guān)知識(shí)的鏈接歸納,方便大家整理資料吧。lua 語言本身提供的調(diào)試就比較簡(jiǎn)潔、加上 Openresty 是嵌入 Nginx 內(nèi)部的,這就更給排查工作帶來了困難。

(1)[官方的調(diào)試頁面]

(http://openresty.org/en/debugging.html )

(2)[官方的性能調(diào)優(yōu)頁面]

(http://openresty.org/en/profiling.html )

(3)[通過systemtap探查在線的Nginx work進(jìn)程]

(https://github.com/agentzh/nginx-systemtap-toolkit)

(4)[額外的工具庫(kù)stap++]

(https://github.com/agentzh/stapxx )

(5)[工具火焰圖Flame Graphs的介紹]

(http://dtrace.org/blogs/brendan/2011/12/16/flame-graphs/ )

(6)[Linux Kernel Performance: Flame Graphs]

(http://dtrace.org/blogs/brendan/2012/03/17/linux-kernel-performance-flame-graphs/ )

【本文是專欄機(jī)構(gòu)“豈安科技”的原創(chuàng)文章,轉(zhuǎn)載請(qǐng)通過微信公眾號(hào)(bigsec)聯(lián)系原作者】


網(wǎng)站標(biāo)題:Openresty的開發(fā)閉環(huán)初探
當(dāng)前地址:http://uogjgqi.cn/article/codgeeg.html
掃二維碼與項(xiàng)目經(jīng)理溝通

我們?cè)谖⑿派?4小時(shí)期待你的聲音

解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流