使用lua+OpenResty+Redis实现多级缓存

思路

使用lua+OpenResty+Redis实现多级缓存_第1张图片

lua脚本

注意点:

  • 注意一定要声明响应头类型,不然返回的是一个文件
  • nginx的用户配置对这个lua脚本文件要有权限
-- 设置响应头类型,不设置会返回文件
ngx.header.content_type="application/json;charset=utf8"
-- 获取url中的参数,? 后面的参数
local uri_args = ngx.req.get_uri_args();
-- 获取参数为id的值
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
    -- 本地缓存为空,向redis中查询
    -- 导入redis module
    local redis = require("resty.redis");
    -- 获取连接对象
    local red = redis:new()
    -- 设置连接超时时间
    red:set_timeout(2000)
    -- redis 的 ip 端口
    local ok, err = red:connect("ip", 6379)
    -- redis设置的密码
    ok, err = red:auth("pwd")
    
    -- reids连接失败的时候
	if not ok then
        -- 记录到nginx日志
    	ngx.log(ngx.DEBUG, "redis connection error:" .. err);
    end

    -- 尝试从redis中获取
    local rescontent=red:get("content_"..id);

    -- 判断redis中的缓存是否为空
    if ngx.null == rescontent then
        -- redis中的缓存为空,从MySQL中获取
        -- 导入json处理相关Module
        local cjson = require("cjson");
        -- 导入MySQL module
        local mysql = require("resty.mysql");
        -- 获取连接对象
        local db = mysql:new();
        -- 超时时间
        db:set_timeout(2000)
        -- MySQL连接相关配置
        local props = {
            host = "ip",
            port = 3306,
            database = "changgou_content",
            user = "root",
            password = "123456"
        }
        -- 连接
        local res = db:connect(props);
        
       -- 拼接SQL语句
        local select_sql = "select url,pic from tb_content where status ='1' and category_id="..id.." order by sort_order";
         -- 执行SQL
        res = db:query(select_sql);
        -- 转为json字符串
        local responsejson = cjson.encode(res);
        -- 设置到redis中
        red:set("content_"..id,responsejson);
        -- 返回给页面
        ngx.say(responsejson);
        -- 关闭MySQL连接
        db:close()
    else
        -- 在redis中有数据,存入本地缓存,10分钟过期时间(首页的广告轮播图更新的频率比较小)
        cache_ngx:set('content_cache_'..id, rescontent, 10*60);
        -- 返回给页面
        ngx.say(rescontent)
    end
    -- 关闭redis连接
    red:close()
else
    -- 在本地缓存中有数据,直接输出
    ngx.say(contentCache)
end

nginx配置

  • 指定lua脚本缓存空间的大小,必须要指定
user  root root;
worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    # 指定lua脚本缓存空间的大小,128MB
    lua_shared_dict dis_cache 128m;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen          80;
        server_name    localhost;
        location / {   
            root   html;
            index  index.html;
        }   
        
        # 当访问轮播数据时交给lua脚本处理
        location /read_content {
            content_by_lua_file /root/lua/cache/read_content.lua;
        }

    }
}

你可能感兴趣的:(Lua脚本,服务端架构,Nginx)