前言
前面的文章中有讲过Lua、nginx和OpenRetry的安装,Redis的安装还没有写,不过网上的教程会很多,所以,大家只要按照下面的文章,把其他的安装配置好即可
【Linux】Lua脚本语言_阿小冰的博客-CSDN博客【Linux】Lua脚本语言https://blog.csdn.net/qq_38377525/article/details/125363317【Linux】OpenRestry安装与应用_阿小冰的博客-CSDN博客【Linux】OpenRestry安装与应用https://blog.csdn.net/qq_38377525/article/details/125364399
场景描述
我接下来要演示的的场景不太好,我主要是为了完成这个功能和给大家展示这个技术的效果,实际上这种功能在电商领域一般会存放广告信息、装修信息等等数据,因为这些数据不易变或者数据庞大,如果在秒杀系统或者流量特别大的门户网站,刚进入主页就调用各种接口去数据库中加载数据并返回然后前端再渲染效果,很明显会降低用户体验并且加长了响应时间,所以一般情况下这种数据,都会实现被缓存下来,那该怎么缓存嘞?那就往下看,接下来我不用广告位那么专业的场景了,因为我有现成的数据库和表数据,所以就借此操作一下实现流程,大家想做其他的场景只要按照实际的mysql配置、SQL编写、Redis配置逐一写上即可
Lua+Nginx配置(存储篇)
1、约定好动作请求地址
http://192.168.80.200/get_user?user_id=4
2、在/root/lua下创建一个get_user.lua文件
文件目的是链接mysql并查询数据,然后存放到redis中
文件内容如下:案例中的数据库是之前讲mycat剩下的,为了方便,这里我直接拿来用
ngx.header.content_type="application/json;charset=utf8" local cjson = require("cjson") local mysql = require("resty.mysql") local uri_args = ngx.req.get_uri_args() local id = uri_args["user_id"] local db = mysql:new() db:set_timeout(1000) local props = { host = "127.0.0.1", port = 3306, database = "mycat_user", user = "root", password = "123456" } local res = db:connect(props) local select_sql = "select user_id,user_name,password from sec_user where user_id="..id.." order by user_id" res = db:query(select_sql) db:close() local redis = require("resty.redis") local red = redis:new() red:set_timeout(2000) local ip ="127.0.0.1" local port = 6379 red:connect(ip,port) red:set("user_"..id,cjson.encode(res)) red:close() ngx.say("{flag:true}")
3、修改nginx配置文件
添加一个location,定义lua缓存命名空间名称和空间大小
配置如下:
4、重启nginx
5、访问接口,执行Lua文件
http://192.168.80.200/get_user?user_id=4
这个文本是lua执行完毕的标记
6、查看是否存入Redis中
到这里,Lua+Nginx+OpenRetry+Redis做缓存数据查询和存储的操作就完毕了
Lua+Nginx配置(读取篇)
1、定义好动作请求地址
http://192.168.80.200/read_user?user_id=4
2、在/root/lua下创建一个read_user.lua文件
内容如下:
--设置响应头类型 ngx.header.content_type="application/json;charset=utf8" --获取请求中的参数ID local uri_args = ngx.req.get_uri_args(); local id = uri_args["user_id"]; --引入redis库 local redis = require("resty.redis"); --创建redis对象 local red = redis:new() --设置超时时间 red:set_timeout(2000) --连接 local ok, err = red:connect("127.0.0.1", 6379) --获取key的值 local rescontent=red:get("user_"..id) --输出到返回响应中 ngx.say(rescontent) --关闭连接 red:close()
3、配置nginx接口信息
4、重启nginx
5、访问接口read_user读取用户信息
这返回的数据,和上面redis存储的数据肯定是一直的了,那到这里就已经完结了
拓展
问题
如果流量很大很大,大家觉得Redis这种吞吐量会不会也会有瓶颈?答案是肯定的,所以为了缓解redis的压力,我们在请求redis之前,再加上一层openRetry本地缓存,其实很简单,就是在read.user.lua脚本中,添加是否存在的判断即可,代码如下
代码
ngx.header.content_type="application/json;charset=utf8" local cjson = require("cjson") local mysql = require("resty.mysql") local uri_args = ngx.req.get_uri_args() local id = uri_args["user_id"] --获取本地缓存,ngx.shared.dis_cache是我们在nginx配置文件中配置的 local cache_ngx = ngx.shared.dis_cache; --根据id获取本地缓存数据 local userCache = cache_ngx:get('user_cache_'..id); --如果本地缓存为空 if userCache == "" or userCache == nil then local redis = require("resty.redis"); local red = redis:new() red:set_timeout(2000) red:connect("127.0.0.1", 6379) local resuser=red:get("user_"..id); if ngx.null == resuser then local cjson = require("cjson"); local mysql = require("resty.mysql"); local db = mysql:new(); db:set_timeout(2000) local props = { host = "127.0.0.1", port = 3306, database = "mycat_user", user = "root", password = "123456" } local res = db:connect(props) local select_sql = "select user_id,user_name,password from sec_user where user_id="..id.." order by user_id" res = db:query(select_sql) local responsejson = cjson.encode(res); red:set("user_"..id,responsejson) ngx.say(responsejson) db:close() else --存入本地缓存 cache_ngx:set('user_cache_'..id, resuser, 10*60); ngx.say(rescontent) end red:close() else --本地缓存中有数据,直接返回 ngx.say(userCache) end
这个就不做具体演示了,上面的步骤没问题的童靴,可以试试这个