# 174. 商品详情页动态渲染系统:完成应用层 nginx 的 lua 脚本的编写与部署

同样这里也不实战了,与之前讲过的 多级缓存 知识点来看,只是多了一个 resty.redis 包的使用, 使用 lua 直接连 redis 获取数据。

local cjson = require("cjson")
local http = require("resty.http")
local redis = require("resty.redis")  

local function close_redis(red)  
	if not red then  
		return  
	end  
	local pool_max_idle_time = 10000
	local pool_size = 100
	local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)  
	if not ok then  
		ngx.say("set keepalive error : ", err)  
	end  
end

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

local cache_ngx = ngx.shared.my_cache
local productCacheKey = "product_"..productId
-- 从本地缓存获取商品信息
local productCache = cache_ngx:get(productCacheKey)

-- 如果本地缓存没有,则从 redis 中获取
if productCache == "" or productCache == nil then
  local red = redis:new()  
  red:set_timeout(1000)  
  local ip = "192.168.31.223"  
  local port = 1112  
  local ok, err = red:connect(ip, port)  
  if not ok then  
    ngx.say("connect to redis error : ", err)  
    return close_redis(red)  
  end

  local redisResp, redisErr = red:get("dim_product_"..productId)
  -- 如果从 redis 中也获取不到数据,则直接从 数据直连服务获取(后面章节会讲解数据直连服务)
  if redisResp == ngx.null then  
    local httpc = http.new()
    local resp, err = httpc:request_uri("http://192.168.31.179:8767",{
      method = "GET",
      path = "/product?productId="..productId
    })

    productCache = resp.body
  end

  productCache = redisResp

  math.randomseed(tostring(os.time()):reverse():sub(1, 7))
  local expireTime = math.random(600, 1200)  
  -- 再延长时间放回本地缓存
  cache_ngx:set(productCacheKey, productCache, expireTime)
end

local context = {
  productInfo = productCache,
}
-- 通过模板渲染返回
local template = require("resty.template")
template.render("product.html", context)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

这里的核心思路就是:如果 nginx local cache 没有,则通过 twemproxy 读本机房的从集群, 如果还是没有,则发送 http 请求给数据直连服务

视频中也只是写了这一个商品的多级缓存实现,品牌、分类数据也是一样的思路(视频中没有实现), 模板也是使用的最简单的信息展示;