- 开辟一块内存空间
在Nginx配置文件conf/nginx.conf中开启了一个内存大小为128M的内存空间,用来存储缓存数据;
- 定义内存字典业务实现lua脚本memory_shared_dic_java.lua(添加缓存,获取缓存)
--- --- 基于lua+Openresty实现内存字典,直接访问redis缓存 --- 引入Redis lua库文件 local red = require "resty.redis" --- 调用new方法,获取redis对象 local redis = red:new() -- local password = "123456"; -- 设置一下redis密码 redis:auth(password) redis:select(0) --- 1、实现缓存的添加操作 function set_to_cache(key,value,expr) if not expr then expr = 0 end --- 获取本地内存字典对象 local ngx_cache = ngx.shared.ngx_cache --- 向内存字典中添加缓存数据 local succ,err,forcible = ngx_cache:set(key,value,expr) return succ end --- 2、从内存字典中获取缓存数据 function get_from_cache(key) --- 获取本地内存字典对象 local ngx_cache = ngx.shared.ngx_cache --- 从内存字典中获取数据缓存 local res = ngx_cache:get(key) -- 如果内存字典缓存不存在 if not res then -- 查询redis缓存数据 local rev,err = get_from_redis(key) if not rev then ngx.say("redis cache not exists",err) return end -- 添加到本地内存字典 set_to_cache(key,rev,60) end return res end --- 向redis添加缓存数据 function set_to_redis(key,value) -- 设置连接Redis的超时时间 redis:set_timeout(10000) -- 连接redis服务器 local ok,err = redis:connect("172.17.61.90",6379) -- 判断连接redis服务是否成功 if not ok then ngx.say("failed to connect:",err) return end -- 如果连接成功,向redis添加缓存数据 local succ,err = redis:set(key,value) if not succ then ngx.say("failed set redis:",err) return end return succ end -- 从Redis中获取缓存数据 function get_from_redis(key) -- 设置连接Redis的超时时间 redis:set_timeout(10000) -- 连接redis服务器 local ok,err = redis:connect("172.17.61.90",6379) -- 判断连接redis服务是否成功 if not ok then ngx.say("failed to connect:",err) return end -- 从Redis中获取缓存数据 local succ,err = redis:get(key) if not succ then ngx.say("failed get redis:",err) return end ngx.say("get cache from redis......") return succ end --- 3、内存字典缓存响应业务实现 --- 获取请求参数 local params = ngx.req.get_uri_args() --- 获取参数属性值 local id = params.id --- 从内存字典中获取数据缓存 local goods = get_from_cache("seckill_goods_"..id) --- 判断内存字典中是否存在缓存数据,如果不存在,将会去查询后端服务数据 if goods == nil then -- 从后端服务查询数据 local result = ngx.location.capture("/seckill/goods/detail/"..id) goods = result.body -- 向内存字典中添加缓存数据 set_to_cache("seckill_goods_"..id,goods,60) end -- 输出结果 ngx.say(goods)
这个lua脚本写好后,上传到Nginx/conf同级目录lua目录下,并且在nginx.conf文件中配置,然后sbin/nginx -s reload生效:
3. java中代码
添加guava依赖
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>18.0</version> </dependency>
@Autowired private SeckillGoodsMapper seckillGoodsMapper; //注入redistemplate对象 @Autowired private RedisTemplate redisTemplate; //注入guva缓存对象 @Autowired private Cache<String,Object> guavaCahce; public TbSeckillGoods findOneByCache(Integer id){ //1、先从jvm堆缓存中读取数据,使用guva缓存 TbSeckillGoods seckillGoods = (TbSeckillGoods) guavaCahce.getIfPresent("seckill_goods_"+id); //判断jvm堆内缓存是否存在 if(seckillGoods == null){ //2、从分布式缓存中查询 seckillGoods = (TbSeckillGoods) redisTemplate.opsForValue().get("seckill_goods_"+id); //判断 if(seckillGoods == null){ //3、直接从数据库查询 seckillGoods = seckillGoodsMapper.selectByPrimaryKey(id); if(seckillGoods != null && seckillGoods.getStatus() == 1){ //添加缓存 redisTemplate.opsForValue().set("seckill_goods_"+id,seckillGoods,1,TimeUnit.HOURS); } } //添加guava缓存 guavaCahce.put("seckill_goods_"+id,seckillGoods); } //如果缓存存在,返回Redis缓存 return seckillGoods; }