亿级流量电商详情页系统实战-31.应用层nginx缓存实现

1.分发到应用层nginx流程

  • 应用nginx的lua脚本接收到请求

  • 获取请求参数中的商品id,以及商品店铺id

  • 根据商品id和商品店铺id,在nginx本地缓存中尝试获取数据

  • 如果在nginx本地缓存中没有获取到数据,那么就到redis分布式缓存中获取数据,如果获取到了数据,还要设置到nginx本地缓存中

    但是这里有个问题,建议不要用nginx+lua直接去获取redis数据。因为openresty没有太好的redis cluster的支持包,所以建议是发送http请求到缓存数据生产服务,由该服务提供一个http接口,缓存数生产服务可以基于redis cluster api从redis中直接获取数据,并返回给nginx。

  • 如果缓存数据生产服务没有在redis分布式缓存中没有获取到数据,那么就在自己本地ehcache中获取数据,返回数据给nginx,也要设置到nginx本地缓存中

  • 如果ehcache本地缓存都没有数据,那么就需要去原始的服务中拉去数据,该服务会从mysql中查询,拉去到数据之后,返回给nginx,并重新设置到ehcache和redis中

  • nginx最终利用获取到的数据,动态渲染网页模板

2.引入相关依赖

#cd /usr/servers/lualib/resty/  
#wget https://codechina.csdn.net/mirrors/pintsized/lua-resty-http/-/tree/master/lib/resty/http_headers.lua  
#wget https://codechina.csdn.net/mirrors/pintsized/lua-resty-http/-/tree/master/lib/resty/http.lua 

#wget https://github.com.com/bungle/lua-resty-template/master/lib/resty/template.lua
#mkdir /usr/servers/lualib/resty/html
#cd /usr/servers/lualib/resty/html
#wget https://github.com/bungle/lua-resty-template/blob/master/lib/resty/template/html.lua

3.规划lua项目结构

/usr/lua/eshop
eshop
    eshop.conf     
    lua              
      product.lua
    templates
      product.html
    lualib            
      *.lua
      *.so
      

4.在nginx中配置eshop.conf

# vi /usr/servers/nginx/conf/nginx.conf

worker_processes  2;  

error_log  logs/error.log;  

events {  
    worker_connections  1024;  
}  

http {  
    include       mime.types;  
    default_type  text/html;  
  
    lua_package_path "/usr/servers/lualib/?.lua;;";  
    lua_package_cpath "/usr/servers/lualib/?.so;;"; 
    lua_shared_dict my_cache 128m;
    include /usr/lua/eshop/eshop.conf;  
}  

5.配置eshop.conf

#mkdir -p /usr/lua/eshop/
#vi /usr/lua/eshop/eshop.conf
server {  
    listen       80;  
    server_name  _;  
    set $template_location "/templates";  
    set $template_root "/usr/lua/eshop/templates";
    location /product{  
        default_type 'text/html';  
        content_by_lua_file /usr/lua/eshop/lua/proudct.lua;  
    }  
}  

6.编写product.html

#mkdir -p /usr/lua/eshop/templates
#vi /usr/lua/eshop/templates/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>

7.编写produc.lua

# mkdir -p /usr/lua/eshop/lua
# vi /usr/lua/eshop/lua/produc.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.9.253:8080",{
  		method = "GET",
  		path = "/getProductInfo?productId="..productId
	})

	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.9.253:8080",{
  		method = "GET",
  		path = "/getShopInfo?shopId="..shopId
	})

	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)

8.nginx动态生效

/usr/servers/nginx/sbin/nginx -s reload

9.测试

http://192.168.135.135/eshop?method=product&productId=1&shopId=1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值