在某些首页进行测试的时候,我们会发现首页的轮播图加载时间过长,严重影响用户体验
所以我们就要对其进行优化。
首先来了解一下258原则
当用户能够在2秒以内得到响应时,会感觉系统的响应很快,用户体验较好;当用户在2-5秒之间得到响应时,虽然没有那么快但是还能接受;但是当用户在5-8秒以内得到响应时,会感觉系统的响应速度明显变慢,就会影响用户体验,可能就会进行吐槽,如果大于8秒,用户体验就会极差,可能就会放弃使用
解决方案:
如果我们开始直接访问的数据库
第一步:使用Redis缓存
测试发现还是不够快,而且还有优化空间,所以进行了进一步的优化
第二步:通过OpenResty整合Lua脚本访问Redis,直接将数据返回给前端页面
分为二级缓存,内部缓存和Redis缓存
缓存预热,定时任务实现MySQL和Redis的同步
缓存预热
使用Lua读取MySQL中的轮播图数据,保存到Redis中
ad_update.lua
-- 获得uri中的sid参数值
local uri_args = ngx.req.get_uri_args()
local sid = uri_args["sid"]
-- 连接mysql
local mysql = require "resty.mysql"
local db = mysql:new()
db:set_timeout(1000)
local ok, err = db:connect{
host = "127.0.0.1",
port = 3306,
database = "edu_ad",
user = "root",
password = "123456",
charset = "utf8"
}
if not ok then
ngx.say("failed to connect: ", err)
return
end
ngx.say("connected to mysql.")
-- 按区域编号查询轮播图表
local res, err = db:query("select * from promotion_ad where space_id="..sid)
if not res then
ngx.say("bad result: ", err)
return
end
db:close()
-- 结果转换为json
local cjson = require "cjson"
ngx.say("res->",cjson.encode(res))
-- 连接redis
local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(2000)
local ok,err = red:connect("127.0.0.1",6379)
if not ok then
ngx.say("connect error: ", err)
return
end
-- 保存到reids
red:set("ad_space_"..sid,cjson.encode(res))
red:close()
ngx.say("updated redis")
将ad_update.lua保存到openresty/nginx/conf/lua目录下
配置nginx.conf
server {
listen 8080;
default_type 'applicaiton/json;charset=utf8';
charset utf-8;
location /ad_update{
default_type text/html;
content_by_lua_file conf/lua/ad_update.lua;
}
}
定时任务
SpringBoot自带Scheduling包提供了任务调度功能
1) 配置类添加注解 @EnableScheduling
2) 在需要调度的方法上添加 @Scheduled注解
3) 配置cron表达式
/**
* {秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)}
* 秒 0-59 , - * /
* 分 0-59 , - * /
* 小时 0-23 , - * /
* 日期 1-31 , - * ? / L W C
* 月份 1-12 或者 JAN-DEC , - * /
* 星期 1-7 或者 SUN-SAT , - * ? / L C #
* 年(可选) 留空, 1970-2099 , - * /
*/
@Scheduled(cron = "*/5 * * * * ?")
常见的cron表达式
*/5 * * * * ? 每隔5秒执行一次
0 */1 * * * ? 每隔1分钟执行一次
0 0 5-15 * * ? 每天5-15点整点触发
0 0/3 * * * ? 每三分钟触发一次
0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发
0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时
0 0 10,14,16 * * ? 每天上午10点,下午2点,4点
0 0 12 ? * WED 表示每个星期三中午12点
0 0 17 ? * TUES,THUR,SAT 每周二、四、六下午五点
0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发
0 15 10 ? * MON-FRI 周一至周五的上午10:15触发
0 0 23 L * ? 每月最后一天23点执行一次
0 15 10 L * ? 每月最后一日的上午10:15触发
0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发
0 15 10 * * ? 2005 2005年的每天上午10:15触发
0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发
0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发"30 * * * * ?" 每半分钟触发任务
"30 10 * * * ?" 每小时的10分30秒触发任务
"30 10 1 * * ?" 每天1点10分30秒触发任务
"30 10 1 20 * ?" 每月20号1点10分30秒触发任务
"30 10 1 20 10 ? *" 每年10月20号1点10分30秒触发任务
"30 10 1 20 10 ? 2011" 2011年10月20号1点10分30秒触发任务
"30 10 1 ? 10 * 2011" 2011年10月每天1点10分30秒触发任务
"30 10 1 ? 10 SUN 2011" 2011年10月每周日1点10分30秒触发任务
"15,30,45 * * * * ?" 每15秒,30秒,45秒时触发任务
"15-45 * * * * ?" 15到45秒内,每秒都触发任务
"15/5 * * * * ?" 每分钟的每15秒开始触发,每隔5秒触发一次
"15-30/5 * * * * ?" 每分钟的15秒到30秒之间开始触发,每隔5秒触发一次
"0 0/3 * * * ?" 每小时的第0分0秒开始,每三分钟触发一次
"0 15 10 ? * MON-FRI" 星期一到星期五的10点15分0秒触发任务
"0 15 10 L * ?" 每个月最后一天的10点15分0秒触发任务
"0 15 10 LW * ?" 每个月最后一个工作日的10点15分0秒触发任务
"0 15 10 ? * 5L" 每个月最后一个星期四的10点15分0秒触发任务
"0 15 10 ? * 5#3" 每个月第三周的星期四的10点15分0秒触发任务
在线cron生成器
缓存读取
分为两级缓存,一级缓存是nginx内部缓存,二级是redis缓存,先读取内部缓存,如果没有再读取redis缓存
ad_load.lua
-- 获得sid参数
local uri_args = ngx.req.get_uri_args()
local sid = uri_args["sid"]
-- 读取内部缓存
local cache = ngx.shared.dis_cache:get('ad_space_'..sid)
if cache == nil then
-- 内部缓存没有读取redis
local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(2000)
local ok, err = red:connect("127.0.0.1", 6379)
local res = red:get('ad_space_'..sid)
ngx.say(res)
red:close()
-- 保存到内部缓存
ngx.shared.dis_cache:set('ad_space_'..sid, res, 10*60)
else
ngx.say(cache)
end
配置nginx.conf
server {
listen 8080;
default_type 'applicaiton/json;charset=utf8';
charset utf-8;
location /ad_update{
default_type text/html;
content_by_lua_file conf/lua/ad_update.lua;
}
location /ad_load{
default_type text/html;
content_by_lua_file conf/lua/ad_load.lua;
}
}
在http模块加内部缓存配置:
lua_shared_dict dis_cache 5m;