Nginx Lua 緩存配置的實現步驟
摘要:
web 應用業(yè)務緩存通常3級:
一級緩存:JVM 本地緩存
二級緩存:Redis集中式緩存
三級緩存:Nginx Proxy Cache 緩存 或 Nginx Lua 緩存
四級緩存:靜態(tài)資源CDN緩存 頁面靜態(tài)化
本文主要分享 Nginx Lua 緩存配置開發(fā)
鑒于 Nginx Proxy Cache 緩存的劣勢,在生產項目中很少使用,如果真正要體現出在距離用戶最近的位置設置緩存,需要使用 Nginx Lua 緩存,才能發(fā)揮出緩存的優(yōu)勢。
Lua 腳本語言出現前,需要使用 c 或 c++ 語言開發(fā)Nginx功能,難度大,風險高。Nginx和Lua集成后,可以通過 Lua 腳本配置 Nignx 。
Nginx Lua 腳本開發(fā)的優(yōu)勢:
協(xié)程機制:
- 協(xié)程是線程內獨立的運行單元,依附于線程的內存模型,切換開銷小。
- 完全可以使用同步方式編寫代碼,不需要考慮異步機制。如果執(zhí)行過程中遇到了類似IO的阻塞事件,會到Nginx異步模型epoll上注冊回調句柄,讓出cpu執(zhí)行權。如果異步模型接收到阻塞事件調用的返回后,喚醒對應的協(xié)程。
- 對共享變量的訪問,都無需加鎖。
Lua 的協(xié)程機制 類似于 Nginx 的協(xié)程機制。
Nginx 協(xié)程
- nginx 每個worker進程都是在epoll或kqueue這種事件模型之上,封閉成協(xié)程。
- 每個請求都有一個協(xié)程處理
- 即使 ngx_lua 相對 C 有一定的開銷,但依舊能保證高并發(fā)能力
- nginx 每個工作進程都創(chuàng)建一個 lua 虛擬機
- 工作進程內所有 協(xié)程 共享 這個 lua 虛擬機
- 每個外部請求都有一個 lua 協(xié)程處理,每個 lua 協(xié)程之間的數據隔離
- lua 代碼調用 io 等異步接口時,協(xié)程被掛起上下文數據,向 epoll select 異步模型上注冊句柄 ,如果異步模型接收到阻塞事件的響應,喚醒協(xié)程,還原協(xié)程上下文,繼續(xù)執(zhí)行代碼。
所以Nginx協(xié)程相比于 JVM的 servlet的多線程機制更高效。
Nginx 生命周期11個處理階段
可以在 Nginx 的生命周期過程中,添加 Lua 控制功能,實現對Nginx功能的配置。
NGX_HTTP_POST_READ_PHASE = 0 // 讀取請求頭
NGX_HTTP_SERVER_REWRITE_PHASE = 0 // 執(zhí)行 uri rewrite rewrite_handler
NGX_HTTP_FIND_CONFIG_PHASE // 根據 uri 替換 location
NGX_HTTP_REWRITE_PHASE // 根據替換結果繼續(xù)執(zhí)行 rewrite rewrite_handler
NGX_HTTP_POST_REWRITE_PHASE // 執(zhí)行 rewrite 后處理
NGX_HTTP_PREACCESS_PHASE // 可以用于處理限流場景
// 認證預處理 請求限制(limit_req_handler) 連接限制(limit_conn_handler)
NGX_HTTP_ACCESS_PHASE // 可用于處理 token 的場景
// 認證處理 auth_basic_handler access_handler
NGX_HTTP_POST_ACCESS_PHASE // 認證后處理 認證不通過 丟包
NGX_HTTP_TRY_FILES_PHASE // 深度 try 標簽
NGX_HTTP_CONTENT_PHASE // 內容處理 static_handler
NGX_HTTP_LOG_PHASE // 日志處理 log_handlerNginx Lua 掛載點
init_by_lua 系統(tǒng)啟動時調用
init_worker_by_lua worker進程啟動時調用
set_by_lua nginx變量使用復雜 lua return
rewrite_by_lua 重寫 url 規(guī)則
access_by_lua 權限驗證階段
content_by_lua 內容輸出階段(使用較多)

OpenResty
OpenResty 的優(yōu)勢:
- 生產項目中可以使用 OpenResty 來進行 Lua 功能開發(fā),因為 OpenResty 以 Nginx 為核心并集成了很多第三方模塊,默認集成了 Lua 開發(fā)環(huán)境,使 Nginx 可以作為 Web Server 使用。
- 借助于 Nginx 的事件驅動模型和非阻塞 IO ,可實現高性能的 Web 應用程序。
- OpenResty 提供了大量組件如 Mysql Redis Memcached 等,使在 Nginx 上開發(fā) web 應用更方便簡單。
OpenResty 可以通過 shared dic 共享內存字典,實現遠超過 proxy cache 性能的緩存,因為 shared dic 對所有 worker 進程都可見,并加成了 LRU 淘汰規(guī)則。再加上 OpenResty 對 Redis 的支持,可以實現更高性能的三級緩存。
nginx.conf
...
# 配置 shared dictionary 的擴展,聲明128m的內存承載共享字典訪問
lua_shared_dict lua_cache 128m;
...
server {
...
# 設置location用來做訪問shared dict的lua文件
location /luadetail/get {
default_type "application/json";
content_by_lua_file ../lua/sharedis.lua
...sharedis.lua
local args = ngx.req.get_uri_args()
local id = args["id"]
local redis = require "resty.redis"
local cache = redis:new()
local ok,err = cache:connect("172.16.16.16", 6379)
local product = cache:get("product_"..id)
if product == ngx.null or product == nil then
local resp = ngx.location.capture("/product/get?id="..id)
product = resp.body
end
ngx.say(product)顯然,Nginx 緩存直接讀取 Redis 中的數據既能保證高效率,也不需要關心緩存中數據的更新失效策略,相比于使用 Nginx 服務器內存作緩存載體更高效。
到此這篇關于Nginx Lua 緩存配置的實現步驟的文章就介紹到這了,更多相關Nginx Lua 緩存內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Nginx中的root&alias文件路徑及索引目錄配置詳解
這篇文章主要介紹了Nginx中的root&alias文件路徑及索引目錄配置,順帶講解了root和alias命令的用法,需要的朋友可以參考下2016-01-01
深入理解Nginx中Server和Location的匹配邏輯
這篇文章主要介紹了深入理解Nginx中Server和Location的匹配邏輯,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-03-03

