原创

广告缓存的载入与读取

1.广告缓存的载入与读取

1.1 需求分析

需要在页面上显示广告的信息。

1.2 Lua+Nginx配置

(1)实现思路-查询数据放入redis中

实现思路:

定义请求:用于查询数据库中的数据更新到redis中。

a.连接mysql ,按照广告分类ID读取广告列表,转换为json字符串。

b.连接redis,将广告列表json字符串存入redis 。

定义请求:

请求:
	/update_content
参数:
	id  --指定广告分类的id
返回值:
	json

请求地址:<http://192.168.211.132/update_content?id=1>

创建/root/lua目录,在该目录下创建update_content.lua: 目的就是连接mysql 查询数据 并存储到redis中。

上图代码如下:

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["id"]

local db = mysql:new()
db:set_timeout(1000)
local props = {
    host = "192.168.211.132",
    port = 3306,
    database = "changgou_content",
    user = "root",
    password = "123456"
}

local res = db:connect(props)
local select_sql = "select url,pic from tb_content where status ='1' and category_id="..id.." order by sort_order"
res = db:query(select_sql)
db:close()

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

local ip ="192.168.211.132"
local port = 6379
red:connect(ip,port)
red:set("content_"..id,cjson.encode(res))
red:close()

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

修改/usr/local/openresty/nginx/conf/nginx.conf文件: 添加头信息,和 location信息

代码如下:

server {
    listen       80;
    server_name  localhost;

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

定义lua缓存命名空间,修改nginx.conf,添加如下代码即可:

代码如下:

lua_shared_dict dis_cache 128m;

请求<http://192.168.211.132/update_content?id=1>可以实现缓存的添加

(2)实现思路-从redis中获取数据

实现思路:

定义请求,用户根据广告分类的ID 获取广告的列表。通过lua脚本直接从redis中获取数据即可。

定义请求:

请求:/read_content
参数:id
返回值:json 

在/root/lua目录下创建read_content.lua:

--设置响应头类型
ngx.header.content_type="application/json;charset=utf8"
--获取请求中的参数ID
local uri_args = ngx.req.get_uri_args();
local id = uri_args["id"];
--引入redis库
local redis = require("resty.redis");
--创建redis对象
local red = redis:new()
--设置超时时间
red:set_timeout(2000)
--连接
local ok, err = red:connect("192.168.211.132", 6379)
--获取key的值
local rescontent=red:get("content_"..id)
--输出到返回响应中
ngx.say(rescontent)
--关闭连接
red:close()

在/usr/local/openresty/nginx/conf/nginx.conf中配置如下:

如图:

代码:

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

(3)加入openresty本地缓存

如上的方式没有问题,但是如果请求都到redis,redis压力也很大,所以我们一般采用多级缓存的方式来减少下游系统的服务压力。参考基本思路图的实现。

先查询openresty本地缓存 如果 没有

再查询redis中的数据,如果没有

再查询mysql中的数据,但凡有数据 则返回即可。

修改read_content.lua文件,代码如下:

上图代码如下:

ngx.header.content_type="application/json;charset=utf8"
local uri_args = ngx.req.get_uri_args();
local id = uri_args["id"];
--获取本地缓存
local cache_ngx = ngx.shared.dis_cache;
--根据ID 获取本地缓存数据
local contentCache = cache_ngx:get('content_cache_'..id);

if contentCache == "" or contentCache == nil then
    local redis = require("resty.redis");
    local red = redis:new()
    red:set_timeout(2000)
    red:connect("192.168.211.132", 6379)
    local rescontent=red:get("content_"..id);

    if ngx.null == rescontent then
        local cjson = require("cjson");
        local mysql = require("resty.mysql");
        local db = mysql:new();
        db:set_timeout(2000)
        local props = {
            host = "192.168.211.132",
            port = 3306,
            database = "changgou_content",
            user = "root",
            password = "123456"
        }
        local res = db:connect(props);
        local select_sql = "select url,pic from tb_content where status ='1' and category_id="..id.." order by sort_order";
        res = db:query(select_sql);
        local responsejson = cjson.encode(res);
        red:set("content_"..id,responsejson);
        ngx.say(responsejson);
        db:close()
    else
        cache_ngx:set('content_cache_'..id, rescontent, 10*60);
        ngx.say(rescontent)
    end
    red:close()
else
    ngx.say(contentCache)
end

测试地址:http://192.168.211.132/update_content?id=1

此时会将分类ID=1的所有广告查询出来,并存入到Redis缓存。

测试地址:http://192.168.211.132/read_content?id=1

此时会获取分类ID=1的所有广告信息。

  • 作者:管理员(联系作者)
  • 发表时间:2020-12-09 22:45
  • 版权声明:自由转载-非商用-非衍生-保持署名
  • 公众号转载:请在文末添加作者公众号二维码
  • 评论

    叮当 游客
    厉害了。大佬