淺談OpenResty在Web應用防火墻中的應用
1、OpenResty起源
OpenResty是一個基于Nginx與Lua的高性能Web平臺,其內部集成了大量精良的Lua庫、第三方模塊以及大多數的依賴項。用于方便地搭建能夠處理超高并發、擴展性極高的動態Web應用、Web服務和動態網關。Nginx由俄羅斯工程師Igor Sysoev于2002年基于C語言開始開發,并于2004年開源,目的是解決Apache HTTP服務器不能滿足C10K(單個HTTP服務器處理10000并發連接)的問題。隨著Web的快速發展普及,Nginx因為其開源、跨平臺、可支持百萬級別的TCP并發連接、高穩定性等優點迅速傳播開來,當前全球有近三分之一的HTTP服務器使用的是Nginx。
Nginx生態的豐富性歸功于由于它高內聚、低耦合的模塊化設計。Nginx提供的主要模塊包括Core模塊、Event模塊、Http模塊、Mail模塊、Stream模塊等。開發者根據Nginx模塊開發規范很容易能擴展Nginx的功能。
Nginx存在局限性:對于一般的業務系統使用Nginx,業務變動僅需要改動Nginx相關配置文件重啟即可,但如果需要開發或者更新第三方模塊則需要重新編譯安裝Nginx,這個對于線上系統是不太友好的,重新編譯安裝Nginx是個操作程度較麻煩和變更風險性較高的過程。由此Nginx對腳本語言的支持是有必要的,Perl、Python、Js、Lua都有C的API,這幾年從開發者的應用來看,Lua這種天然就是C的腳本語言使用最廣泛。Lua腳本可以很容易的被C/C++ 代碼調用,也可以反過來調用C/C++的函數,一個完整的Lua解釋器不過200k,在所有腳本引擎中,Lua的速度是最快的。
OpenResty應運而生:基于Nginx,OpenResty通過LuaJIT擴展支持,讓開發者可以使用Lua腳本語言調動Nginx支持的各種C以及Lua模塊,大大提高了Nginx模塊開發的生產力。
2、OpenResty工作原理
OpenResty本質是基于Nginx的單Master多Worker進程模型,將LuaVM嵌入到進程中,通過LuaVM來執行Lua代碼獲得高性能,同時LuaVM的自動內存管理也提高了開發者的開發效率。OpenResty的兩大技術特點:(1)多階段處理;(2)Lua協程與Nginx event的高效NIO結合。下面分別介紹。
2.1 OpenResty的多階段處理
OpenResty的多階段處理基于Nginx的HTTP多階段處理。如前介紹,Nginx對Http的處理也是一個個HTTP模塊協作完成的,對于HTTP模塊,數據的流轉,銜接等管理,Nginx將它劃分成11個處理階段,每個處理階段由多個HTTP模塊進行流水線處理:
OpenResty將這11個階段簡化成Rewrite/Access Phase、Content Phase、 LogPhase,加上進程啟動初始化的Initialization Phase共四個大階段11個*_by_lua可重寫指令。
每個階段分工清晰,各個階段處理http請求不同階段的數據,分層更易于理解和開發。
2.2 Lua協程與Nginx Event的NIO結合
對于Http請求的處理,性能消耗主要在網絡IO處理,Nginx相對于Apache Server多線程模型處理效率高的原因就是在于Nginx的Event處理機制。具體到Linux,Event處理機制基于Epoll實現,所有讀寫事件不會阻塞主線程,而是注冊到epoll,主線程通過調用epoll_wait來獲取可讀寫事件,對準備好的事件進行相應的回調處理,實現非阻塞IO。回到OpenResty,每個Worker進程有一個LuaVM,OpenResty通過LuaVM來執行Lua代碼,每個外部請求都通過一個Lua協程來處理,每個協程互不影響,每當Lua代碼需要處理IO時,都會yield當前協程,將IO事件交給Nginx的Event處理,這樣就不會阻塞Worker主線程,待Nginx的Event處理完畢,Resume協程繼續處理。協程僅在用戶態處理相對于多線程切換的開銷少。通過協程結合和Nginx的非阻塞I/O模型,不僅僅對HTTP客戶端請求,甚至于對遠程后端諸如MySQL、PostgreSQL、Memcached以及Redis等都進行一致的高性能響應。
3、OpenResty在網站安全建設中的應用
中國移動貫眾安全云WAF是一款網站應用防火墻產品,通過對Http/Https流量的分析檢測,攔截惡意流量,為Web業務安全運營提供保障。截至目前,中國移動貫眾安全云WAF已為超2000家站點提供網站安全防護服務。團隊在研發之初做技術選型時就采用了OpenResty,主要考慮它的一下優點:
- 降低開發門檻,Lua庫極其豐富,研發效率高,能適應功能快速迭代的需求;
- 很容易支持熱更新,研發、測試、發布效率高,對業務無感知;
- 云原生支持,裸機,容器等都可以部署維護;
- 高性能,基于Nginx的高性能Http應用,對MySQL、Redis等也支持非阻塞IO。
貫眾安全云WAF部署架構圖大致如下:
由于WAF節點是串接在系統內的,這對WAF節點的性能和穩定性有較高要求,如圖所示,我們通過DPVS+KeepAlived做四層負載均衡保障包的高速轉發和可靠性,后面直接通過OpenResty集群進行流量的分析。經過WAF的流量都經過了十幾個步驟的檢測,各個步驟相互獨立,互不影響,非阻塞的IO保障了檢測的性能。主要使用到的階段如下:
如上表所示,每個階段互相配合,分工明確,配置和云WAF配置中心實時同步,能熱更新業務配置、防護配置、規則庫等,運維成本低。防護階段對性能要求高的檢測手段會用C寫成動態庫,Lua的ffi能很方便調用,和需要存儲、統計運算的均采用cosocket和數據庫交互,非阻塞的特性保障和數據庫交互的高性能。
4、總結
OpenResty是一個基于Nginx和Lua的優秀開源組件,保留了Nginx的高性能的同時,引入Lua,降低了開發門檻,研發效率高,運維成本低。對于有大量Web平臺需要治理的企業比較試用。可以基于OpenResty二次開發動態路由、限流、緩存、權限控制、安全防護等能力,替代Nginx管理企業內部站點。
參考文獻
[1]OpenResty.http://openresty.org/cn/.
[2]陶輝. 深入理解nginx:模塊開發與架構解析[M]. 機械工業出版社. 2013-4.
[3]Lua Nginx Module. https://github.com/openresty/lua-nginx-module.