NginxLua的介紹與應(yīng)用_第1頁
NginxLua的介紹與應(yīng)用_第2頁
NginxLua的介紹與應(yīng)用_第3頁
NginxLua的介紹與應(yīng)用_第4頁
NginxLua的介紹與應(yīng)用_第5頁
已閱讀5頁,還剩49頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

lua&ngx_lua的介紹與應(yīng)用by陳于喆QQ:34174409大綱Lua的預(yù)備知識架構(gòu)背景nginx的預(yù)備知識ngx_luanginx,lua,ngx_lua再說原理思考lua的預(yù)備知識什么是lua嚕啊Lua是一種腳本編程語言,于1994年,由巴西里約熱內(nèi)盧天主教大學(xué)的研究人員設(shè)計(jì)開發(fā),“Lua”這個(gè)名字是葡萄牙語單詞“月亮”。小鳥引發(fā)熱潮2011年6月排名lua的特點(diǎn)與一般腳本語言如PHP、Perl、JavaScript等不同,Lua被稱為是一種嵌入式腳本語言,Lua最著名的應(yīng)用是在暴雪公司的網(wǎng)絡(luò)游戲魔獸世界和網(wǎng)易的大話西游中。Lua最引人注目的特點(diǎn):極小的體積和簡單的語法提供相對全面的功能。簡潔的API實(shí)現(xiàn)與宿主語言最方便的接口。與平臺無關(guān)幾乎運(yùn)行于所有的系統(tǒng)。所謂的“嵌入式”lua可以獨(dú)立進(jìn)行編程,但這不是主要的使用方式。Lua雖然有動態(tài)、靈活的語法提供強(qiáng)大的功能,但并不像Java、Python等一樣有一個(gè)完善的庫,這不是缺陷,而是和其定位有關(guān)?!扒度胧健?,lua作為一個(gè)庫,嵌入到其他大型語言(稱之為宿主語言)的應(yīng)用程序之中,為應(yīng)用程序提供參數(shù)配置或邏輯描述等功能,帶來前所未有的靈活性。lua的經(jīng)典使用方式宿主語言lua作為配置文件,為宿主語言提供參數(shù)宿主語言為底層庫,lua作為邏輯處理宿主語言lualua工作流程4執(zhí)行讀入的Lua程序3讀入Lua源程序或預(yù)先編譯后的Lua程序2將宿主語言實(shí)現(xiàn)的Lua擴(kuò)展,如函數(shù)等,注冊到Lua解釋器中,供其使用1宿主語言建立Lua解釋器對象。Lua與宿主語言的交互方式宿主語言通過虛擬機(jī)對Lua腳本中的變量實(shí)現(xiàn)增、刪、讀、寫宿主語言通過虛擬機(jī)調(diào)用Lua腳本中的函數(shù)宿主語言定義新的數(shù)據(jù)類型供Lua腳本使用Lua調(diào)用宿主語言編寫的函數(shù)Lua與C宿主的交互~1進(jìn)行編譯gcc-ohellohello.c-llua–dl運(yùn)行./hello(有備注)更深入的交互上例只實(shí)現(xiàn)了對Lua腳本的解析,并沒有實(shí)現(xiàn)Lua與宿主語言的數(shù)據(jù)交換和互操作。和典型的腳本語言引擎相同,Lua虛擬機(jī)是一個(gè)堆棧機(jī),其一切運(yùn)算基本都在堆棧上完成,這個(gè)堆棧也是LuaAPI的關(guān)鍵部分,是Lua與宿主語言交換數(shù)據(jù)的手段。12堆棧機(jī)的原理實(shí)現(xiàn)計(jì)算f(a,b,c)先將函數(shù)壓棧再將參數(shù)依次壓棧函數(shù)執(zhí)行后將參數(shù)彈出并將結(jié)果壓棧13通過堆棧的交互用宿主語言可以編寫供Lua調(diào)用的函數(shù),宿主語言需要遵守調(diào)用約定,從棧中取得參數(shù),最后也將結(jié)果入棧。將宿主函數(shù)通過lua_register注冊入Lua虛擬機(jī)(這一過程實(shí)質(zhì)為向Lua語言添加全局變量),就可以被Lua語言所調(diào)用。Lua虛擬機(jī)的堆棧Lua虛擬機(jī)內(nèi)部有一個(gè)堆棧,LuaAPI提供了對其的操作,不僅有出入棧操作,還可以以數(shù)組的形式,通過索引值隨機(jī)讀寫棧元素,這是雙方交換數(shù)據(jù)的主要方式。Lua與C宿主的交互~2Hello2.cHello2.lua進(jìn)行編譯gcc-ohello2hello2.c-llua–dl運(yùn)行./hello2(有備注)結(jié)果分析(lua_State*s):數(shù)據(jù)傳遞不通過其參數(shù),而是通過堆棧;整型返回值指明了該函數(shù)真正向Lua返回的值的個(gè)數(shù),即壓棧的結(jié)果個(gè)數(shù)。函數(shù)返回后,Lua虛擬機(jī)會自動進(jìn)行清棧工作,不需在函數(shù)內(nèi)部來做。注意:在Lua中函數(shù)可以有不止一個(gè)返回值17基本類型賦值:a=3 x,y,z=12,'Hello',true基本類型:空類型nil nil數(shù)值number 123 3.14159 1.6e-9運(yùn)算:+-*/%^(乘冪)-(負(fù))布爾boolean true false運(yùn)算:orandnot字符串string ‘’ “你好"運(yùn)算:..(連接)#(長度)其他通用運(yùn)算符:==~=><>=<=tableLua使用table類型作為一切數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ):t={1234,nil,'hello',true,{'nested',1.414}}table本質(zhì)為哈希表,保存鍵-值對的集合,若不指定鍵,則默認(rèn)為從1開始的整數(shù)。也可顯式指定鍵:rec={[‘name’]=‘111',favorite=‘222',[10]=true}引用表的元素: rec['favorite'] rec[10]活用表類型,可以構(gòu)成結(jié)構(gòu)體、鏈表、數(shù)組、對象等各種復(fù)雜數(shù)據(jù)結(jié)構(gòu)。(有備注)關(guān)于閉包functionnewCounter()locali=0 returnfunction() i=i+1 returni endendc1=newCounter()print(c1())print(c1())(有備注)20架構(gòu)背景2108年我們的框架BrowserApacheAPPDBLVSsquidBusiness目前我們的架構(gòu)BrowserNginxAPPDBLVSBusinessContentCDNhttpsqsajax404proxy得到的收益業(yè)務(wù)更加穩(wěn)定–Nginx大連接數(shù)目支持非常好–Nginx本身的內(nèi)存占用很少,不會吃swap業(yè)務(wù)性能更高–QPS比Apache要好–節(jié)省機(jī)器數(shù)目–基于Nginx的模塊性能往往是之前業(yè)務(wù)的數(shù)倍Nginx的知識預(yù)備Nginx進(jìn)程模式nginx采用多進(jìn)程,單Master多WorkerMaster處理外部信號,配置文件以及worker的初始化worker進(jìn)程采用單線程,非阻塞(Eventloop)來處理客戶端請求和響應(yīng)Nginx處理Http請求的過程clientserverlocationIp

hostporturlphaseNginx處理Http請求的過程N(yùn)GX_HTTP_POST_READ_PHASE

讀取請求phaseNGX_HTTP_SERVER_REWRITE_PHASE

這個(gè)階段主要是處理全局的(serverblock)的rewriteNGX_HTTP_FIND_CONFIG_PHASE

這個(gè)階段主要是通過uri來查找對應(yīng)的location,然后根據(jù)loc_conf設(shè)置r的相應(yīng)變量NGX_HTTP_REWRITE_PHASE

這個(gè)主要處理location的rewriteNGX_HTTP_POST_REWRITE_PHASE

postrewrite,這個(gè)主要是進(jìn)行一些校驗(yàn)以及收尾工作,以便于交給后面的模塊。

NGX_HTTP_PREACCESS_PHASE

比如流控這種類型的access就放在這個(gè)phase,也就是說它主要是進(jìn)行一些比較粗粒度的access。Nginx處理Http請求的過程N(yùn)GX_HTTP_ACCESS_PHASE

這個(gè)比如存取控制,權(quán)限驗(yàn)證就放在這個(gè)phase,一般來說處理動作是交給下面的模塊做的.這個(gè)主要是做一些細(xì)粒度的accessNGX_HTTP_POST_ACCESS_PHASE

一般來說當(dāng)上面的access模塊得到access_code之后就會由這個(gè)模塊根據(jù)access_code來進(jìn)行操作NGX_HTTP_TRY_FILES_PHASE

try_file模塊,就是對應(yīng)配置文件中的try_files指令,可接收多個(gè)路徑作為參數(shù),當(dāng)前一個(gè)路徑的資源無法找到,則自動查找下一個(gè)路徑NGX_HTTP_CONTENT_PHASE

內(nèi)容處理模塊NGX_HTTP_LOG_PHASE

log模塊子請求(subrequest)location/main{echo_location/foo;}location/foo{echofoo;}“子請求”方式的通信是在同一個(gè)虛擬主機(jī)內(nèi)部進(jìn)行的,所以Nginx核心在實(shí)現(xiàn)“子請求”的時(shí)候,就只調(diào)用了若干個(gè)C函數(shù),完全不涉及任何網(wǎng)絡(luò)或者UNIX套接字(socket)通信。我們由此可以看出“子請求”的執(zhí)行效率是極高的。(有備注)協(xié)程協(xié)程類似一種多線程,與多線程的區(qū)別有:協(xié)程并非os線程,所以創(chuàng)建、切換開銷比線程相對要小。協(xié)程與線程一樣有自己的棧、局部變量等,但是協(xié)程的棧是在用戶進(jìn)程空間模擬的,所以創(chuàng)建、切換開銷很小。多線程程序是多個(gè)線程并發(fā)執(zhí)行,也就是說在一瞬間有多個(gè)控制流在執(zhí)行。而協(xié)程強(qiáng)調(diào)的是一種多個(gè)協(xié)程間協(xié)作的關(guān)系,只有當(dāng)一個(gè)協(xié)程主動放棄執(zhí)行權(quán),另一個(gè)協(xié)程才能獲得執(zhí)行權(quán),所以在某一瞬間,多個(gè)協(xié)程間只有一個(gè)在運(yùn)行。由于多個(gè)協(xié)程時(shí)只有一個(gè)在運(yùn)行,所以對于臨界區(qū)的訪問不需要加鎖,而多線程的情況則必須加鎖。多線程程序由于有多個(gè)控制流,所以程序的行為不可控,而多個(gè)協(xié)程的執(zhí)行是由開發(fā)者定義的所以是可控的。31協(xié)程(簡單的說)協(xié)程(coroutine)和線程的區(qū)別在于調(diào)度方式的差異,即讓出CPU給別的執(zhí)行緒(切換)的時(shí)機(jī)不同:

線程:主動讓出(yield)、I/O阻塞、時(shí)間片到 協(xié)程:主動讓出(yield)、I/O(協(xié)程間通信)阻塞32Ngx_lua33Ngx_lua安裝下載http_lua_module,加載編譯或直接使用openresty./configure--with-luajit&&make&&makeinstall/ngx_lua的用法ngx_lua模塊提供了配置指令和NginxAPI。配置指令:在Nginx中使用,和set指令和pass_proxy指令使用方法一樣,每個(gè)指令都有使用的上下文(context)NginxAPI:用于在Lua腳本中訪問Nginx變量,調(diào)用Nginx提供的函數(shù)。35配置指令set_by_lua/set_by_lua_fileaccess_by_lua/access_by_lua_filerewrite_by_lua/rewrite_by_lua_filecontent_by_lua/content_by_lua_file36set_by_luahttp://ip:8083/adder?a=100&b=100

和set指令一樣用于設(shè)置Nginx變量并且在rewrite階段執(zhí)行,只不過這個(gè)變量是由lua腳本計(jì)算并返回的access_by_luahttp://ip:8083/auth運(yùn)行在access階段,用于訪問控制。Nginx原生的allow和deny是基于ip的,通過access_by_lua能完成復(fù)雜的訪問控制,比如,訪問數(shù)據(jù)庫進(jìn)行用戶名、密碼驗(yàn)證等rewrite_by_luahttp://ip:8083/rew實(shí)現(xiàn)url重寫,在rewrite階段執(zhí)行39content_by_lua在content階段執(zhí)行,生成http響應(yīng)http://ip:8083/hello1例子:抵御hash攻擊curl--data"a=1&a=11&b=d"http://ip:8083/limit/1.html302or405例子:配合memcachedrequire('Memcached')Module&requireMemcached模塊引用了socket動態(tài)編譯庫(有備注)42例子:ip控制43例子:與php簡單的io比對寫入5MB約1s-2s寫入5MB約10s-12shttp://ip/xf/iotest.phphttp://ip:8083/io_testio:nginx&luacontent_by_lua'res=ngx.location.capture("/subreq")echores.body';local

f

=

assert(io.open("html/index.html","r"))

在Lua中進(jìn)行各種IO時(shí),都要通過ngx.location.capture發(fā)送子請求委托給Nginx事件模型,這樣可以保證IO是非阻塞的location

/subreq

{

internal;

root

html;

}

(有備注)45再說nginx,lua,ngx

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論