Nginx+Lua多级缓存实战(获取活动详情)

Nginx+Lua多级缓存实战

介绍

创建活动表

CREATE TABLE `activitt_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL COMMENT '活动名称',
`desc` varchar(3000) DEFAULT NULL COMMENT '活动介绍',
`starttime` datetime DEFAULT NULL,
`endtime` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

链接MySQL封装

创建一个lua脚本 mysql.lua ,用于提供根据SQL语句执行查询操作,代码如下:

--MySQL查询操作,封装成一个模块
--Java操作MySqL
--导入依赖包
local mysql = require "resty.mysql"

--配置数据源链接
local props = {
    host = "192.168.139.187",
    port = 3306,
    database = "redpackage",
    user = "root",
    password = "sunfeng"
}

--创建一个对象
local mysqldb = {}


--查询数据库
function mysqldb.query(sql)
	--创建链接
	local db = mysql:new()
	--设置超时时间
	db:set_timeout(10000)
	db:connect(props)
	--配置编码格式
	db:query("SET NAMES utf8")
	--查询数据库 "select * from activity_info where id=1"
	local result = db:query(sql)
	--关闭链接
	db:close()
	--返回结果集
	return result
end

return mysqldb

Lua链接Redis集群封装

我们需要安装 lua-resty-redis-cluster ,用该依赖库实现Redis集群的操作,这里提供github地址,大家下载后按操作配置即可,下载地址: https://github.com/cuiweixie/lua-resty-redis-cluster ,下载该文件后通过centos7 openresty使用Lua连接Redis集群配置,即可实现Redis集群操作
接下来我们实现Redis集群操作,创建一个脚本 redis.lua ,脚本中实现Redis中数据的查询和添加操作,代码如下

--操作Redis集群,封装成一个模块
--引入依赖库
local redis_cluster = require "resty.rediscluster"

--配置Redis集群链接信息
local config = {
    name = "test",
    serv_list = {
        {ip="192.168.139.187", port = 7001},
        {ip="192.168.139.187", port = 7002},
        {ip="192.168.139.187", port = 7003},
        {ip="192.168.139.187", port = 7004},
        {ip="192.168.139.187", port = 7005},
        {ip="192.168.139.187", port = 7006},
    },
    idle_timeout    = 1000,
    pool_size       = 10000,
}

--定义一个对象
local lredis = {}

--创建set()添加数据方法
function lredis.set(key,value)
	--1)打开链接
	local red = redis_cluster:new(config)
	red:init_pipeline()

	--2)执行命令【set】
	red:set(key,value)
	red:commit_pipeline()

	--3)关闭链接
	red:close()
end


--创建查询数据get()
function lredis.get(key)
	--1)打开链接
	local red = redis_cluster:new(config)
	red:init_pipeline()

	--2)执行命令【set】
	red:get(key)
	local result = red:commit_pipeline()

	--3)关闭链接
	red:close()
	
	--4)返回结果集
	return result
end


return lredis

多级缓存操作

配置Nginx缓存空间,此代码配置在nginxhttp代码块中

   #定义Nginx缓存
   lua_shared_dict act_cache 128m;

创建多级缓存操作脚本 activity.lua ,代码如下:

--多级缓存流程操作
--1)Lua脚本查询Nginx缓存
--2)Nginx如果没有缓存
--2.1)Lua脚本查询Redis
--2.1.1)Redis如果有数据,则将数据存入到Nginx缓存,并响应用户
--2.1.2)Redis没有数据,Lua脚本查询MySQL
--       MySQL有数据,则将数据存入到Redis、Nginx缓存[需要额外定义],响应用户
--3)Nginx如果有缓存,则直接将缓存响应给用户



--响应数据为JSON类型
ngx.header.content_type="application/json;charset=utf8"
--引入依赖库
--cjson:对象转JSON或者JSON转对象
local cjson = require("cjson")
local mysql = require("mysql")
local lrredis = require("redis")

--获取请求参数ID   http://192.168.139.187/act?id=1
local id = ngx.req.get_uri_args()["id"];

--加载本地缓存
local cache_ngx = ngx.shared.act_cache;

--组装本地缓存的key,并获取nginx本地缓存
local ngx_key = 'ngx_act_cache_'..id
local actCache = cache_ngx:get(ngx_key)

--如果nginx中没有缓存,则查询Redis集群缓存
if actCache == "" or actCache == nil then
	--从Redis集群中加载数据
	local redis_key = 'redis_act_'..id
	local result = lrredis.get(redis_key)
	
	--Redis中数据为空,查询数据库
	if result[1]==nil or result[1]==ngx.null then
		--组装SQL语句
		local sql = "select * from activity_info where id ="..id
		--执行查询
		result = mysql.query(sql)
		--数据不为空,则添加到Redis中
		if result[1]==nil or result[1]==ngx.null then
			ngx.say("no data")
		else
			--数据添加到Nginx缓存和Redis缓存
			lrredis.set(redis_key,cjson.encode(result))
			cache_ngx:set(ngx_key, cjson.encode(result), 2*60);
			ngx.say(cjson.encode(result))
		end
	else
		--将数据添加到Nginx缓存中
		cache_ngx:set(ngx_key, result, 2*60);
		--直接输出
		ngx.say(result)
	end
else
	--输出缓存数据
	ngx.say(actCache)
end

Nginx配置

#活动查询
location /act {
	content_by_lua_file /usr/local/openresty/nginx/lua/activity.lua;
}

查询结果
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值