1、前言
Lua和OpenResty安装请参考该链接:https://blog.csdn.net/pkxwyf/article/details/105360507
2、需求分析
类似京东首页的广告数据显示:
3、广告缓存架构概述
- 查询Ngin缓存,如果有缓存则直接将缓存中的广告数据返回
- 如果Nginx缓存中没有广告数据,则通过Lua脚本查询Redis,如果Redis中有数据,则将数据存入到Nginx的缓存并返回查询到广告数据。
- 如果Redis中没有缓存数据,则此时会通过Lua脚本查询MySQL,如果MySQL有数据,则将数据存入到Redis中并返回查询到数据。
4、广告表结构
4.1、广告分类表
CREATE TABLE `tb_content_category` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
4.2、广告表
CREATE TABLE `tb_content` (
`id` bigint NOT NULL AUTO_INCREMENT,
`category_id` bigint NOT NULL,
`title` varchar(200) DEFAULT NULL,
`url` varchar(500) DEFAULT NULL,
`pic` varchar(300) DEFAULT NULL,
`status` varchar(1) DEFAULT NULL,
`sort_order` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
5、代码实现
5.1、缓存预热
缓存预热就是将数据提前加入到缓存中,当数据发生变更,再将最新的数据更新到缓存。
5.1.1、实现思路
- 定义请求:用于查询MySQL数据库中的数据更新到redis中。
- 连接Mysql 按照广告分类ID读取广告列表,转换为json字符串。
- 连接Redis将广告列表json字符串存入redis 。
5.1.2、实现步骤
- 定义请求:请求地址:/content_update 请求参数:id -- 广告分类id 返回值:json
- 在/root/lua目录下创建content_update.lua 实现连接Mysql 查询数据 并存储到Redis中。
ngx.header.content_type="application/json;charset=utf-8";
local id= ngx.req.get_uri_args()["id"];--提取参数
local cjson= require("cjson"); --加载cjson模块
local mysql= require("resty.mysql");--加载mysql模块
local redis= require("resty.redis");--加载redis模块
--读取mysql中的数据
local db= mysql:new();
local props = {
host = "192.168.33.133",
port = 3306,
database ="changgou_content",
user ="root",
password ="root"
}
db:connect(props);
local select_sql="select pic,url from tb_content where status = '1' and category_id="..id.." order by sort_orde
r ";
local res=db:query(select_sql);
db:close();
--写入redis
local red= redis:new();
red:connect("192.168.33.133",6379);
red:set("content_"..id,cjson.encode(res));
red:close();
ngx.say("{falg:true,code:20000}");
- 修改 /usr/local/openresty/nginx/conf/nginx.conf 文件
location /content_update {
content_by_lua_file /root/lua/content_update.lua;
}
- 重新启动nginx并测试:http://192.168.33.133/content_update?id=1
5.2、广告缓存读取
5.2.1、实现思路
- 定义请求:用户根据广告分类的ID 获取广告的列表
- 从Nginx缓存获取,获取到直接返回广告数据,否则执行下一步
- 从Redis中获取广告数据,获取到则将广告数据存入Nginx缓存中
5.2.2、实现步骤
- 定义请求:请求地址:/content_read 请求参数:id -- 广告分类id 返回值:json
- 在/root/lua目录下创建content_read.lua 实现查询nginx缓存数据
ngx.header.content_type="application/json;charset=utf‐8";
‐‐提取参数:广告分类id
local id= ngx.req.get_uri_args()["id"];
‐‐加载本地缓存模块
local cache_ngx= ngx.shared.dis_cache;
‐‐从本地缓存获取广告数据
local content_cache = cache_ngx:get("content_"..id);
‐‐ 如果本地缓存没有数据
if content_cache =="" or content_cache == nil then
‐‐引入redis模块
local redis= require("resty.redis");
‐‐实例化redis对象
local red = redis:new();
‐‐建立连接
red:connect("192.168.33.133",6379);
‐‐从redis取值
local data= red:get("content_"..id);
‐‐关闭连接
red:close();
ngx.say(data);
‐‐存入本地缓存
cache_ngx:set("content_"..id , data);
else
ngx.say(content_cache);
end
- 修改 /usr/local/openresty/nginx/conf/nginx.conf 文件
location /content_read {
content_by_lua_file /root/lua/content_read.lua;
}
- 重新启动nginx并测试:http://192.168.33.133/content_read?id=1