基于Memcached+Nginx+Lua的商品详情页html缓存方案

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/bless2015/article/details/84753006

Memcached是一个高性能的K-V键值对缓存,其设计的目的就是为了减少与数据库的交互,保存静态数据信息,与Redis的区别。

前言

在设计商品详情页时,由于信息加载较多,需要考虑加载时间、性能问题。说白了既要保证用户体验,下单流程的完整性,又要尽量减少与数据库的交互。而这部分数据偏静态,这部分数据可以做后台渲染和缓存。我们将详情页按照业务模块和性质拆分成多个子链接访问,这里以商品信息展示(名称、价格、折扣等)为例进行说明。
总结一下我们要做的一件事:后端渲染,减少与数据库的访问,以提高页面打开速度。

文件树



Memcached

这里用的memcached的windows版本,里面也包含了启动教程,不再做过多的解释。

Nginx

首先看Nginx的配置文件

server{
	listen 8888;
	server_name localhost;
	lua_code_cache on;
	location /memcached {
		root lua;
		content_by_lua_file '../openresty-1.13.6.1-win32/lua/memcached.lua';
	}
}

将发送到下面的请求映射到memcached.lua文件

http://localhost:8888/memcached

lua

lua一共做了两件事:memcached交互和后端渲染
下面看lua文件的逻辑

local memcached = require "resty.memcached"
--创建memcached实例
local memc, err = memcached:new()
  if not memc then
      ngx.say("failed to instantiate memc: ", err)
      return
  end
--设置请求超时时间
  memc:set_timeout(1000) -- 1 sec
  --创建连接
  local ok, err = memc:connect("127.0.0.1", 11211)
  if not ok then
      ngx.say("failed to connect: ", err)
      return
  end

--根据传入的productId做为键
  local res, flags, err = memc:get("key_demo")
  if err then
      ngx.say("failed to get key_demo: ", err)
      return
  end

  if not res then
      ngx.say("key_demonot found")
      return
  end

  ngx.say("key_demo: ", res)
--memcached尽量设置长连接,减少3次握手的时间
  local ok, err = memc:set_keepalive(10000, 100)
  if not ok then
      ngx.say("cannot set keepalive: ", err)
      return
  end

以上是创建lua与memcached连接的几个过程,下面根据思路来依次介绍整个流程。

获取url的传参

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

获取数据

给服务端发送http请求获取数据库数据(第一次访问时,memcached中并没有数据)

local http = require "resty.http"
local httpc = http.new()
local cjon=require "cjson"
local url= ""
local res,err = httpc.request_uri(url,{method="GET",path="/api/product?productId="..key})
local result
if not res then
	ngx.log(ngx.WARN,'failed to request',err)
	return
else
	result =cjson.decode(res.body)

数据渲染

将json数据渲染到html中,首先创建html模版productdetail.html。css略,但是貌似css只能用style标签和html写在一起。

<div>
	<table>
		<tr>
			<th>商品名称</th>
			<th>{{product.ProductName}}</th>
		</tr>
		<tr>
			<th>商品价格</th>
			<th>{{product.ProductPrice}}</th>
		</tr>
		<tr>
			<th>商品折扣率</th>
			<th>{{product.ProductRate}}</th>
		</tr>
	</table>
</div>

模版写完后,如果没配置路径,和lua文件放到同一级下。
渲染方式,接上面的,result是返回的json反序列化串。

扫描二维码关注公众号,回复: 4351583 查看本文章
local template = require "resty.template"
local context = {prodct=result}
local func = template.compile("productdetail.html")
local content = func(context)

这时候content里存出的是渲染后的html代码,可以把这段代码直接输出给前端。

代码

memcached.lua

local memcached = require "resty.memcached"
local cjon=require "cjson"
args=ngx.req.get_uri_args()
local key = args["productId"]
--创建memcached实例
local memc, err = memcached:new()
  if not memc then
      ngx.say("failed to instantiate memc: ", err)
      return
  end

--设置请求超时时间
memc:set_timeout(1000) -- 1 sec
--创建连接
local ok, err = memc:connect("127.0.0.1", 11211)
if not ok then
    ngx.say("failed to connect: ", err)
    return
end
--设置长连接
local ok ,err = memc:set_keepalive(10000,100)
if not ok then
    ngx.say("failed to keepalive", err)
    return
end
--根据传入的productId做为键
local res, flags, err = memc:get(key)
if not res then
    --从数据库拿数据
	local template = require "resty.template"
	local http = require "resty.http"
	local httpc = http.new()
	local cjon=require "cjson"
	local url= ""
	local res,err = httpc.request_uri(url,{method="GET",path="/api/product?productId="..key})
	local result
	if not res then
		ngx.log(ngx.WARN,'failed to request',err)
		return
	else
		result =cjson.decode(res.body)
	end
	local context = {prodct=result}
	local func = template.compile("productdetail.html")
	local content = func(context)
	local ok, err = memc:set(key,content)
	if not ok then
		ngx.say("failed to insert to memcached")
		return
	end
	ngx.say(content)
end
--从缓存读
ngx.say(res)

productdetail.html代码

<div>
	<table>
		<tr>
			<th>商品名称</th>
			<th>{{product.ProductName}}</th>
		</tr>
		<tr>
			<th>商品价格</th>
			<th>{{product.ProductPrice}}</th>
		</tr>
		<tr>
			<th>商品折扣率</th>
			<th>{{product.ProductRate}}</th>
		</tr>
	</table>
</div>

nginx配置

worker_processes 1;
events{
	worker_connections 1024;
}
http {
	lua_package_path "../openresty-1.13.6.1-win32/lua/?.lua;../openresty-1.13.6.1-win32/lualib/?.lua"
	server{
	listen 8888;
	server_name localhost;
	lua_code_cache on;
	location /memcached {
		root lua;
		content_by_lua_file '../openresty-1.13.6.1-win32/lua/memcached.lua';
	}
}

Memcached连接

telnet 127.0.0.1 11211

可以查看内存分块,他这里叫chunk。使用情况。

效果

第一次读库,接口520ms
在这里插入图片描述

第二次访问,从memcacahed中读,72ms
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/bless2015/article/details/84753006
今日推荐