local token = uuid.generate();
local restOut = { resp_code = 0, resp_msg = “操作成功”, datas = {} };
local errorOut = { resp_code = -1, resp_msg = “操作失败”, datas = {} };
local seckillSha = nil;
–创建自定义的redis操作对象
local red = redisExecutor:new();
–打开连接
red:open();
–获取lua脚本的sha1 编码
seckillSha=red:getValue(“lua:sha1:seckill”);
–redis没有缓存秒杀脚本
if not seckillSha or seckillSha == ngx.null then
errorOut.resp_msg=“秒杀还未启动”;
ngx.say(cjson.encode(errorOut));
–归还连接到连接池 red:close();
return ;
end
–执行秒杀脚本
local rawFlag = red:evalSeckillSha(seckillSha, “setToken”, goodId, userId, token);
–归还连接到连接池
red:close();
if not rawFlag or rawFlag == ngx.null then
ngx.say(cjson.encode(errorOut));
return ;
end
local flag = tonumber(rawFlag);
if flag == 5 then
errorOut.resp_msg = “已经排队过了”;
ngx.say(cjson.encode(errorOut));
return ;
end
if flag == 2 then
errorOut.resp_msg = “秒杀商品没有找到”;
ngx.say(cjson.encode(errorOut));
return ;
end
if flag == 4 then
errorOut.resp_msg = “库存不足,稍后再来”;
ngx.say(cjson.encode(errorOut));
return ;
end
if flag ~= 1 then
errorOut.resp_msg = “排队失败,未知错误”;
ngx.say(cjson.encode(errorOut));
return ;
end
restOut.datas = token;
ngx.say(cjson.encode(restOut));
Lua脚本:执行令牌桶限流
=============
Nginx的令牌桶限流脚本getToken_access_limit.lua执行在请求的access阶段,但是该脚本并没有实现限流的核心逻辑,仅仅调用缓存在Redis内部的rate_limiter.lua脚本进行限流。
getToken_access_limit.lua脚本和rate_limiter.lua脚本的关系如图10-17所示。
图10-17 getToken_access_limit.lua脚本和rate_limiter.lua脚本的 关系
什么时候在Redis中加载rate_limiter.lua脚本呢?和秒杀脚本一样,该脚本是在Java程序启动商品秒杀时完成其在Redis的加载和缓存的。还有一点非常重要,Java程序会将脚本加载完成之后的sha1编码通过自定义的key(具体为lua:sha1:rate_limiter)缓存在Redis中,以方便Nginx的getToken_access_limit.lua脚本获取,并且在调用evalsha方法时使用。
getToken_access_limit.lua脚本的代码如下:
此脚本的环境
内部
不是运行在
内部—此脚本的环境:Nginx内部,不是运行在Redis内部
—启动调试
–local mobdebug = require(“luaScript.initial.mobdebug”);
–mobdebug.start();
–导入自定义的基础模块
–local basic = require(“luaScript.module.common.basic”);
–导入自定义的RedisOperator模块
local redisExecutor = require(“luaScript.redis.RedisOperator”);
–读取post参数
ngx.req.read_body();
local data = ngx.req.get_body_data(); --获取消息体
local args = cjson.decode(data);
local goodId = args[“seckillGoodId”];
local userId = args[“userId”];
local errorOut = { resp_code = -1, resp_msg = “限流出错”, datas = {} };
local key=“rate_limiter:seckill:”…goodId;
local rateLimiterSha = nil;
–创建自定义的Redis操作对象
local red = redisExecutor:new();
–打开连接
red:open();
–获取限流Lua脚本的sha1编码
rateLimiterSha=red:getValue(“lua:sha1:rate_limiter”);
–Redis没有缓存秒杀脚本
if not rateLimiterSha or rateLimiterSha == ngx.null then
errorOut.resp_msg=“秒杀还未启动,请先设置商品”;
ngx.say(cjson.encode(errorOut));
–归还连接到连接池
red:close();
return ;
end
local connection=red:getConnection();
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
面试题总结
其它面试题(springboot、mybatis、并发、java中高级面试总结等)
中…(img-HV4KROVO-1710410708408)]
面试题总结
其它面试题(springboot、mybatis、并发、java中高级面试总结等)
[外链图片转存中…(img-GTNLPDki-1710410708408)]
[外链图片转存中…(img-7WpLBQJV-1710410708409)]
[外链图片转存中…(img-XhYZHlxx-1710410708409)]