上一篇 “分發(fā)層 + 應(yīng)用層” 雙層nginx 架構(gòu) 之 分發(fā), 主要講解了基于openResty部署 nginx 分發(fā)層,及如何提高nginx 緩存命中率,本篇繼續(xù)上兩篇話題,實現(xiàn)應(yīng)用層數(shù)據(jù)緩存更新,為模板提供數(shù)據(jù)來源。
應(yīng)用層 nginx 思路邏輯
- 分發(fā)層nginx 請求應(yīng)用層,nginx lua 接收請求
- 獲取請求參數(shù)
- 根據(jù)請求參數(shù)到nginx本地緩存獲取數(shù)據(jù)
- nginx 本地緩存沒有數(shù)據(jù),請求緩存服務(wù)(數(shù)據(jù)獲取
順序: redis > ehcache > mysql)獲取數(shù)據(jù),并設(shè)置本地緩存 - nginx 數(shù)據(jù)組裝,動態(tài)渲染網(wǎng)頁模板,響應(yīng)分發(fā)層nginx
下面利用上兩篇準(zhǔn)備好的環(huán)境,來實現(xiàn)上面邏輯,以下操作基于應(yīng)用層nginx (192.168.0.16,192.168.0.17)來操作
為了實現(xiàn)以上邏輯,我們還需要為nginx 提供http、template 支持,因此需要為應(yīng)用層nginx test 項目引入http 、template 依賴
引入 http 依賴
cd /usr/local/test/lualib/resty
wget https://raw.githubusercontent.com/pintsized/lua-resty-http/master/lib/resty/http_headers.lua
wget https://raw.githubusercontent.com/pintsized/lua-resty-http/master/lib/resty/http.lua
引入 template 依賴
cd /usr/local/test/lualib/resty
wget https://raw.githubusercontent.com/bungle/lua-resty-template/master/lib/resty/template.lua
mkdir /usr/local/test/lualib/resty/html
cd /usr/local/test/lualib/resty/html
wget https://raw.githubusercontent.com/bungle/lua-resty-template/master/lib/resty/template/html.lua
創(chuàng)建html 模板位置,編寫 html templates 模板代碼
- 創(chuàng)建模板路徑
mkdir /usr/local/test/templates
- 編寫模板代碼 - product.html
vim product.html
加入以下代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>商品詳情頁</title>
</head>
<body>
商品id: {* productId *}<br/>
商品名稱: {* productName *}<br/>
商品圖片列表: {* productPictureList *}<br/>
商品規(guī)格: {* productSpecification *}<br/>
商品售后服務(wù): {* productService *}<br/>
商品顏色: {* productColor *}<br/>
商品大小: {* productSize *}<br/>
店鋪id: {* shopId *}<br/>
店鋪名稱: {* shopName *}<br/>
店鋪等級: {* shopLevel *}<br/>
店鋪好評率: {* shopRate*}<br/>
</body>
</html>
定義 nginx 本地緩存
cd /usr/local/servers/nginx/conf && vim nginx.conf
在 http 里面加上以下內(nèi)容:
lua_shared_dict test_cache 128m; 聲明一個 大小128m 的 test_cache 對象
在test 項目中配置 template 路徑信息
vim /usr/local/test/test.conf
在 server 里面加上以下內(nèi)容:
set $template_location "/templates";
set $template_root "/usr/local/test/templates";
實現(xiàn)應(yīng)用層nginx 代碼邏輯
vim /usr/local/test/lua/test.lua
代碼如下:
// 獲取請求參數(shù)
local uri_args = ngx.req.get_uri_args()
local product_id = uri_args["productId"]
local shop_id = uri_args["shopId"]
// 獲取之前聲明的test_cache 緩存對象
local cache_ngx = ngx.shared.test_cache
//組裝商品、店鋪緩存key
local product_cache_key = "product_info_"..product_id
local shop_cache_key = "shop_info_"..shop_id
// 從nginx 本地緩存中獲取商品、店鋪信息
local product_cache = cache_ngx:get(product_cache_key)
local shop_cache = cache_ngx:get(shop_cache_key)
// 判斷 商品緩存 是否有數(shù)據(jù),如果沒有,發(fā)送請求到商品緩存服務(wù)獲取
if product_cache == "" or product_cache == nil then
local http = require("resty.http")
local httpc = http.new()
// 發(fā)送請求到商品緩存服務(wù)獲取
local resp, err = httpc:request_uri("http://192.168.0.3:81",{
method = "GET",
path = "/getProductInfo?productId="..product_id
})
// 獲取請求響應(yīng)數(shù)據(jù),并設(shè)置nginx 本地緩存,過期時間為 10 分鐘
product_cache = resp.body
cache_ngx:set(product_cache_key, product_cache, 10 * 60)
end
// 判斷 店鋪緩存 是否有數(shù)據(jù),如果沒有,發(fā)送請求到店鋪緩存服務(wù)獲取
if shop_cache == "" or shop_cache == nil then
local http = require("resty.http")
local httpc = http.new()
// 發(fā)送請求到店鋪緩存服務(wù)獲取
local resp, err = httpc:request_uri("http://192.168.0.3:81",{
method = "GET",
path = "/getShopInfo?shopId="..shop_id
})
// 獲取請求響應(yīng)數(shù)據(jù),并設(shè)置nginx 本地緩存,過期時間為 10 分鐘
shop_cache = resp.body
cache_ngx:set(shop_cache_key, shop_cache, 10 * 60)
end
// 引入json 解析類庫
local cjson = require("cjson")
// 對商品、店鋪數(shù)據(jù)進(jìn)行json 轉(zhuǎn)換
local product_cache_json = cjson.decode(product_cache)
local shop_cache_json = cjson.decode(shop_cache)
// 構(gòu)造模板渲染對象
local context = {
productId = product_cache_json.id,
productName = product_cache_json.name,
productPrice = product_cache_json.price,
productPictureList = product_cache_json.pictureList,
productSecification = product_cache_json.secification,
productService = product_cache_json.service,
productColor = product_cache_json.color,
productSize = product_cache_json.size,
shopId = shop_cache_json.id,
shopName = shop_cache_json.name,
shopLevel = shop_cache_json.level,
shopRate = shop_cache_json.rate
}
// 引入template 解析渲染類庫
local template = require("resty.template")
// 渲染模板
template.render("product.html", context)
驗證應(yīng)用層
nginx 校驗 及 重載
/usr/local/servers/nginx/sbin/nginx -t && /usr/local/servers/nginx/sbin/nginx -s reload
瀏覽器驗證
通過上面可以看出,當(dāng)?shù)谝淮卧L問是,應(yīng)用層nginx 緩存沒有數(shù)據(jù),故請求后端服務(wù)獲取數(shù)據(jù);第二次請求是,直接nginx 緩存取數(shù)據(jù),沒有走后端服務(wù)。
總結(jié):用戶請求nginx 后,首先從nginx 本地緩存獲取數(shù)據(jù),后端服務(wù)獲取。這里我們的目的就達(dá)到了
以上就是本章內(nèi)容,如有不對的地方,請多多指教,謝謝!
為了方便有需要的人,本系列全部軟件都在 https://pan.baidu.com/s/1qYsJZfY
下章預(yù)告:主要講解 分布式緩存重建并發(fā)沖突問題以及zookeeper分布式鎖解決方案
作者:逐暗者 (轉(zhuǎn)載請注明出處)