基于nginx+lua+redis实现数据二级缓存

广告二级缓存,加载实现思路

缓存预热:编写lua脚本实现缓存预热(将mysql里的数据查询出来存入redis)
二级缓存查询:编写lua脚本实现二级缓存查询(openresty先从本地获取数据 如果没有数据 则从redis里获取并存入本地)

步骤一:编写lua脚本实现缓存预热(将mysql里的数据查询出来存入redis)在这里插入图片描述
步骤二:编写lua脚本实现二级缓存读取 (openresty先从本地获取数据 如果没有数据 则从redis里获取并存入本地)在这里插入图片描述

缓存预热 (通过lua从mysql里写入redis)

1.实现思路:

定义请求:用于查询数据库中的数据更新到redis中。
(1)连接mysql ,按照广告分类ID读取广告列表,转换为json字符串。
(2)连接redis,将广告列表json字符串存入redis 。

2.定义请求:

请求: /ad_update
参数: position ‐‐指定广告位置
返回值: json

3. 编写lua脚本

在/root/lua目录下创建ad_update.lua ,实现连接mysql 查询数据 并存储到redis中。

ngx.header.content_type="application/json;charset=utf8"   --响应方式
local cjson = require("cjson")    --引入cjson
local mysql = require("resty.mysql")    -- 引入mysql
local uri_args = ngx.req.get_uri_args()
local position = uri_args["position"]

local db = mysql:new()  --开启mysql的新连接
db:set_timeout(1000)
local props = {
    host = "192.168.200.128",
    port = 3306,
    database = "changgou_business",
    user = "root",
    password = "root"
}

local res = db:connect(props)
local select_sql = "select url,image from tb_ad where status ='1' and position='"..position.."' and start_time<= NOW() AND end_time>= NOW()" 
res = db:query(select_sql)   --执行sql语句
db:close()  -- 关闭mysql

local redis = require("resty.redis")
local red = redis:new()
red:set_timeout(2000)

local ip ="192.168.200.128"
local port = 6379
red:connect(ip,port)

red:set("ad_"..position,cjson.encode(res))   -- 向redis存放什么内容
red:close()

ngx.say("{flag:true}")

4.修改nginx配置文件,添加执行lua脚本的请求

修改/usr/local/openresty/nginx/conf/nginx.conf文件:

代码如下 一访问ad_update 路径 就会从数据库读数据写入reids里

在这里插入图片描述

5.重新启动nginx

在这里插入图片描述

6.测试

测试:http://虚拟机地址/ad_update?position=web_index_lb

将数据从mysql里写入redis 然后查看redis里的数据 (如果没有数据 注意上方lua语句中sql语句的时间条件
再看数据库中是否符合)
在这里插入图片描述

扫描二维码关注公众号,回复: 9605460 查看本文章

广告缓存读取 (一级缓存读取,读取redis)

1.实现思路:

通过lua脚本直接从redis中获取数据即可。

2.定义请求:

请求:/ad_read
参数:position
返回值:json

3.编写lua脚本

在/root/lua目录下创建ad_read.lua (读取redis里的数据)

ngx.header.content_type="application/json;charset=utf8"

local uri_args = ngx.req.get_uri_args();
local position = uri_args["position"];

local redis = require("resty.redis");

local red = redis:new()

red:set_timeout(2000)

local ok, err = red:connect("192.168.200.128", 6379)

local rescontent=red:get("ad_"..position)

ngx.say(rescontent)

red:close()

4.修改nginx配置文件,添加执行lua脚本的请求

在/usr/local/openresty/nginx/conf/nginx.conf中server下添加配置

location /ad_read {
    content_by_lua_file /root/lua/ad_read.lua; 
}

5.重启nginx

6.测试

测试 http://192.168.200.128/ad_read?position=web_index_lb 输出

[{"url":"img\/banner1.jpg","image":"img\/banner1.jpg"},
{"url":"img\/banner2.jpg","image":"img\/banner2.jpg"}]

二级缓存—加入openresty本地缓存

如上的方式没有问题,但是如果请求都到redis,redis压力也很大,所以我们一般采用多级缓存的方式来减少下游系统的服务压力。
先查询openresty本地缓存 如果没有再查询redis中的数据

1. 修改读取数据的lua脚本

修改/root/lua目录下ad_read文件, 内容如下:

先查询本地缓存,如果有直接返回,如果没有数据,进行redis的缓存查询,并添加到本地缓存中。

ngx.header.content_type="application/json;charset=utf8"
local uri_args = ngx.req.get_uri_args();
local position = uri_args["position"];
local cache_ngx = ngx.shared.dis_cache;  --开启本地缓存
local adCache = cache_ngx:get('ad_cache_'..position);  --在本地缓存中查询相关数据
if adCache == "" or adCache == nil then     --本地缓存没内容 查询redis
    local redis = require("resty.redis");   
    local red = redis:new()
    red:set_timeout(2000)
    local ok, err = red:connect("192.168.200.128", 6379)
    local rescontent=red:get("ad_"..position)
    ngx.say(rescontent)
    red:close()
    cache_ngx:set('ad_cache_'..position, rescontent, 10*60);   -- 从redis保存到本地缓存
else
    ngx.say(adCache)
end

2. 修改nginx配置,开启共享内存

修改nginx配置文件vi /usr/local/openresty/nginx/conf/nginx.conf ,http节点下添加配置 (放到最后一行)

#包含redis初始化模块 
lua_shared_dict dis_cache 5m; #共享内存开启

3.重启nginx

前端页面实现(了解)

在页面上添加

(1)修改index.html,编写脚本

在这里插入图片描述

(2)修改index.html,渲染广告轮播图在这里插入图片描述

(3)上传至服务器并测试

更改nginx的配置文件

在这里插入图片描述

发布了31 篇原创文章 · 获赞 8 · 访问量 1516

猜你喜欢

转载自blog.csdn.net/qq_37126480/article/details/104463975