第四节:千万级流量下商品详情页的全套方案和压测分析
一. 整体业务再次分析
详细分析:
二.
1. 封装 requestTemplateRendering.lua 文件,用来抓取网页文件,放到openresty下的script文件夹中。
查看代码
local template = require("resty.template")
local lrredis = require("redisUtils")
local lgethtml = require("requestHtml")
local lreqparm = require("requestUtils")
--获取请求参数
local reqParams = lreqparm.getRequestParam()
-- 定义本地缓存
local html_template_cache = ngx.shared.html_template_cache
-- 获取请求ID的参数
local reqId = reqParams["id"];
ngx.log(ngx.INFO, "requestID:", reqId);
-- 校验参数
if reqId==nil then
ngx.say("缺少ID参数");
return
end
-- 布隆过滤器检查id是否存在
local bfexist = lrredis.bfexists("bf_taxi",reqId)
ngx.log(ngx.INFO, "布隆过滤器检验:", bfexist)
-- 校验key不存在直接返回
if bfexist==0 then
ngx.say("布隆过滤器校验key不存在...")
return
end
-- 拼接hget的key
local hgetkey = "hkey_".. reqId
-- 通过hget获取map的所有数据
local templateData = lrredis.hgetall(hgetkey);
if next(templateData) == nil then
ngx.say("redis没有存储数据...")
return
end
--获取模板价格数据
local amount = templateData["amount"]
ngx.log(ngx.INFO, "amount:", amount)
if amount == nil then
ngx.say("价格数据未配置");
return
end
-- 获取本地缓存对象
ngx.log(ngx.INFO, "开始从缓存中获取模板数据----")
local html_template = html_template_cache:get(reqId)
-- 判断本地缓存是否存在
if html_template == nil then
-- 获取模板url中的数据
ngx.log(ngx.INFO, "缓存中不存在数据开始远程获取模板")
local url = templateData["url"]
ngx.log(ngx.INFO, "从缓存中获取的url地址:", url)
if url == nil then
ngx.say("URL路径未配置");
return
end
-- 抓取远程url的html
ngx.log(ngx.INFO, "开始抓取模板数据:", url)
local returnResult = lgethtml.gethtml(url);
-- 判断抓取模板是否正常
if returnResult==nil then
ngx.say("抓取URL失败...");
return
end
-- 判断html状态
if returnResult.status==200 then
html_template = returnResult.body
--设置模板缓存为一小时
ngx.log(ngx.INFO, "将模板数据加入到本地缓存")
html_template_cache:set(reqId,html_template,60 * 60)
end
end
ngx.log(ngx.INFO, "缓存中获取模板数据结束----")
-- 模板渲染
--编译得到一个lua函数
local func = template.compile(html_template)
local context = {amount=amount}
ngx.log(ngx.INFO, "开始渲染模板数据")
--执行函数,得到渲染之后的内容
local content = func(context)
--通过ngx API输出
ngx.say(content)
2. 配置nginx
(1). 配置本地缓存
# 配置模板缓存
lua_shared_dict html_template_cache 10m;
(2). 配置server
# 6. 千万流量的全套方案
server {
listen 8888;
charset utf-8;
server_name test2.hi-whales.com;
# 配置路径重写
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
rewrite ^/(.*) http://test1.hi-whales.com/$1 permanent;
}
#删除本地缓存
location /delete {
default_type text/html;
content_by_lua '
local lreqparm = require("requestUtils")
--获取请求参数
local reqParams = lreqparm.getRequestParam()
-- 定义本地缓存
local html_template_cache = ngx.shared.html_template_cache
-- 获取请求ID的参数
local reqId = reqParams["id"];
ngx.log(ngx.INFO, "requestID:", reqId);
-- 校验参数
if reqId==nil then
ngx.say("缺少ID参数");
return
end
-- 获取本地缓存对象
html_template_cache:delete(reqId);
ngx.say("清除缓存成功");
';
}
location /template {
default_type text/html;
content_by_lua_file /root/mydevelop/openresty/script/requestTemplateRendering.lua;
# content_by_lua ' ngx.say("<p>hhhhh") ';
}
}
3.初始化数据
#连接redis
redis-cli -c -h 127.0.0.1 -p 6380 -a 123456
# 在redis中添加一个布隆过滤器 错误率是0.01 数量是1万个
BF.RESERVE bf_taxi 0.01 10000 NONSCALING
# 在bf_test 的布隆过滤器添加一个key
BF.ADD bf_taxi 1001
#检查数据是否存在
BF.EXISTS bf_taxi 1001
# 添加URL以及价格
hset hkey_1001 url http://8.130.72.40/index.html amount 4999
4. 访问
http://test2.hi-whales.com:8888/template?id=1001 ,如下图,大功告成
访问:http://test2.hi-whales.com:8888/template?id=1002
三. 压测
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 :
- 声 明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。