54_基於nginx+lua+java完成多級緩存架構的核心業務邏輯


分發層nginx,lua應用,會將商品id,商品店鋪id,都轉發到後端的應用nginxhtml

/usr/servers/nginx/sbin/nginx -s reloadmysql

一、應用nginx的lua腳本接收到請求nginx

二、獲取請求參數中的商品id,以及商品店鋪idgit

三、根據商品id和商品店鋪id,在nginx本地緩存中嘗試獲取數據github

四、若是在nginx本地緩存中沒有獲取到數據,那麼就到redis分佈式緩存中獲取數據,若是獲取到了數據,還要設置到nginx本地緩存中redis

可是這裏有個問題,建議不要用nginx+lua直接去獲取redis數據sql

由於openresty沒有太好的redis cluster的支持包,因此建議是發送http請求到緩存數據生產服務,由該服務提供一個http接口json

緩存數生產服務能夠基於redis cluster api從redis中直接獲取數據,並返回給nginx後端

cd /usr/hello/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 api

五、若是緩存數據生產服務沒有在redis分佈式緩存中沒有獲取到數據,那麼就在本身本地ehcache中獲取數據,返回數據給nginx,也要設置到nginx本地緩存中

六、若是ehcache本地緩存都沒有數據,那麼就須要去原始的服務中拉去數據,該服務會從mysql中查詢,拉去到數據以後,返回給nginx,並從新設置到ehcache和redis中

這裏先不考慮,後面要專門講解一套分佈式緩存重建併發衝突的問題和解決方案

七、nginx最終利用獲取到的數據,動態渲染網頁模板

cd /usr/hello/lualib/resty/
wget https://raw.githubusercontent.com/bungle/lua-resty-template/master/lib/resty/template.lua
mkdir /usr/hello/lualib/resty/html
cd /usr/hello/lualib/resty/html
wget https://raw.githubusercontent.com/bungle/lua-resty-template/master/lib/resty/template/html.lua

在hello.conf的server中配置模板位置

set $template_location "/templates";
set $template_root "/usr/hello/templates";

mkdir /usr/hello/templates

vi product.html

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>商品詳情頁</title>
</head>
<body>
商品id: {* productId *}<br/>
商品名稱: {* productName *}<br/>
商品圖片列表: {* productPictureList *}<br/>
商品規格: {* productSpecification *}<br/>
商品售後服務: {* productService *}<br/>
商品顏色: {* productColor *}<br/>
商品大小: {* productSize *}<br/>
店鋪id: {* shopId *}<br/>
店鋪名稱: {* shopName *}<br/>
店鋪等級: {* shopLevel *}<br/>
店鋪好評率: {* shopGoodCommentRate *}<br/>
</body>
</html>

八、將渲染後的網頁模板做爲http響應,返回給分發層nginx

hello.conf中:

lua_shared_dict my_cache 128m;

lua腳本中:

local uri_args = ngx.req.get_uri_args()
local productId = uri_args["productId"]
local shopId = uri_args["shopId"]

local cache_ngx = ngx.shared.my_cache

local productCacheKey = "product_info_"..productId
local shopCacheKey = "shop_info_"..shopId

local productCache = cache_ngx:get(productCacheKey)
local shopCache = cache_ngx:get(shopCacheKey)

if productCache == "" or productCache == nil then
local http = require("resty.http")
local httpc = http.new()

local resp, err = httpc:request_uri("http://192.168.31.179:8080",{
method = "GET",
path = "/getProductInfo?productId="..productId,
keepalive=false
})

productCache = resp.body
cache_ngx:set(productCacheKey, productCache, 10 * 60)
end

if shopCache == "" or shopCache == nil then
local http = require("resty.http")
local httpc = http.new()

local resp, err = httpc:request_uri("http://192.168.31.179:8080",{
method = "GET",
path = "/getShopInfo?shopId="..shopId,
keepalive=false
})

shopCache = resp.body
cache_ngx:set(shopCacheKey, shopCache, 10 * 60)
end

local cjson = require("cjson")
local productCacheJSON = cjson.decode(productCache)
local shopCacheJSON = cjson.decode(shopCache)

local context = {
productId = productCacheJSON.id,
productName = productCacheJSON.name,
productPrice = productCacheJSON.price,
productPictureList = productCacheJSON.pictureList,
productSpecification = productCacheJSON.specification,
productService = productCacheJSON.service,
productColor = productCacheJSON.color,
productSize = productCacheJSON.size,
shopId = shopCacheJSON.id,
shopName = shopCacheJSON.name,
shopLevel = shopCacheJSON.level,
shopGoodCommentRate = shopCacheJSON.goodCommentRate
}

local template = require("resty.template")
template.render("product.html", context)

 

 

第一次訪問的時候,其實在nginx本地緩存中是取不到的,因此會發送http請求到後端的緩存服務裏去獲取,會從redis中獲取

拿到數據之後,會放到nginx本地緩存裏面去,過時時間是10分鐘

而後將全部數據渲染到模板中,返回模板

之後再來訪問的時候,就會直接從nginx本地緩存區獲取數據了

緩存數據生產 -> 有數據變動 -> 主動更新兩級緩存(ehcache+redis)-> 緩存維度化拆分

分發層nginx + 應用層nginx -> 自定義流量分發策略提升緩存命中率

nginx shared dict緩存 -> 緩存服務 -> redis -> ehcache -> 渲染html模板 -> 返回頁面

還差最後一個很關鍵的要點,就是若是你的數據在nginx -> redis -> ehcache三級緩存都不在了,可能就是被LRU清理掉了

這個時候緩存服務會從新拉去數據,去更新到ehcache和redis中,這裏咱們還沒講解

分佈式的緩存重建的併發問題

相關文章
相關標籤/搜索