微服务框架
【SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】
多级缓存
文章目录
- 微服务框架
- 多级缓存
- 48 多级缓存
- 48.8 查询Redis 缓存
- 48.8.1 OpenResty的Redis模块
48 多级缓存
48.8 查询Redis 缓存
48.8.1 OpenResty的Redis模块
OpenResty提供了操作Redis的模块,我们只要引入该模块就能直接使用:【是真的强】
- 引入Redis模块,并初始化Redis对象
看看目录
OK,就是这个,因为它不是直接放在 lualib 下
所以要加个目录名
- 封装函数,用来释放Redis连接,其实是放入连接池
【读取Redis】
- 封装函数,从Redis读数据并返回
编写【common.lua 】
-- 导入redis
local redis = require("resty.redis")
-- 初始化Redis对象
local red = redis:new()
-- 设置Redis超时时间
red:set_timeouts(1000, 1000, 1000)
-- 关闭redis连接的工具方法,其实是放入连接池
local function close_redis(red)
local pool_max_idle_time = 10000 -- 连接的空闲时间,单位是毫秒
local pool_size = 100 --连接池大小
local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
if not ok then
ngx.log(ngx.ERR, "放入redis连接池失败: ", err)
end
end
-- 查询redis的方法 ip和port是redis地址,key是查询的key
local function read_redis(ip, port, key)
-- 获取一个连接
local ok, err = red:connect(ip, port)
if not ok then
ngx.log(ngx.ERR, "连接redis失败 : ", err)
return nil
end
-- 查询redis
local resp, err = red:get(key)
-- 查询失败处理
if not resp then
ngx.log(ngx.ERR, "查询Redis失败: ", err, ", key = " , key)
end
--得到的数据为空处理
if resp == ngx.null then
resp = nil
ngx.log(ngx.ERR, "查询Redis数据为空, key = ", key)
end
close_redis(red)
return resp
end
-- 封装函数,发送http请求,并解析响应
local function read_http(path, params)
local resp = ngx.location.capture(path,{
method = ngx.HTTP_GET,
args = params,
})
if not resp then
-- 记录错误信息,返回404
ngx.log(ngx.ERR, "http查询失败, path: ", path , ", args: ", args)
ngx.exit(404)
end
return resp.body
end
-- 将方法导出
local _M = {
read_http = read_http
read_redis = read_redis
}
return _M
item.lua
OK,再看看案例
【案例】查询商品时,优先Redis缓存查询
需求:
- 修改item.lua,封装一个函数read_data,实现先查询Redis,如果未命中,再查询tomcat
- 修改item.lua,查询商品和库存时都调用read_data这个函数
-- 导入common 函数库
local common = require('common')
local read_http = common.read_http
local read_redis = common.read_redis
-- 导入cjson 库
local cjson = require('cjson')
-- 封装查询函数
function read_data(key , path, params)
-- 优先查询Redis
local resp = read_redis("127.0.0.1", 6379, key)
-- 判断查询结果
if not resp then
ngx.log("redis查询失败,尝试查询http,key : " , key)
-- redis 查询失败,去查询http
resp = read_http(path , params)
end
return resp
end
-- 获取路径参数
local id = ngx.var[1]
-- 查询商品信息
local itemJSON = read_data("item:id:" .. id , "/item/" .. id,nil)
-- 查询库存信息
local stockJSON = read_data("item:stock:id:" .. id ,"/item/stock/" .. id , nil)
-- JSON 转化为lua 的table
local item = cjson.decode(itemJSON)
local stock = cjson.decode(stockJSON)
-- 组合数据
item.stock = stock.stock
item.sold = stock.sold
-- -- 返回结果
-- ngx.say(itemJSON)
-- 把item 序列化为json,返回结果
ngx.say(cjson.encode(item))
OK
重新加载一下
万事俱备
打包项目上传 到服务器上
跑起来
OK,缓存预热也做好了
直接访问浏览器
… 500 了
看看
【笔者又恢复到 了没加缓存的样子】
感觉是集群的问题
一步一步排查一下
卧槽!!!我这儿 少了一个逗号
我淦,我说没这句就能正常运行,有了这句就挂了
可以的
接下去
-- 导入common 函数库
local common = require('common')
local read_http = common.read_http
local read_redis = common.read_redis
-- 导入cjson 库
local cjson = require('cjson')
-- 封装查询函数
function read_data(key , path, params)
-- 优先查询Redis
local resp = read_redis("1.13.92.88", 6379, key)
-- 判断查询结果
if not resp then
ngx.log("redis查询失败,尝试查询http,key : " , key)
-- redis 查询失败,去查询http
resp = read_http(path , params)
end
return resp
end
-- 获取路径参数
local id = ngx.var[1]
-- 有缓存
-- 查询商品信息
local itemJSON = read_data("item:id:" .. id,"/item/" .. id,nil)
-- 查询库存信息
local stockJSON = read_data("item:stock:id:" .. id,"/item/stock/" .. id , nil)
-- 没加缓存
-- -- 查询商品信息
-- local itemJSON = read_http("/item/" .. id,nil)
-- -- 查询库存信息
-- local stockJSON = read_http("/item/stock/" .. id , nil)
-- JSON 转化为lua 的table
local item = cjson.decode(itemJSON)
local stock = cjson.decode(stockJSON)
-- 组合数据
item.stock = stock.stock
item.sold = stock.sold
-- -- 返回结果
-- ngx.say(itemJSON)
-- 把item 序列化为json,返回结果
ngx.say(cjson.encode(item))
OK了
终于成功 了,
现在把两个Tomcat 服务器停掉
看看这次能不能拿到数据
没毛病,说明服务器停掉了也能从Redis 中获取数据!!!!
牛逼!!!!!