设为首页 收藏本站
查看: 1029|回复: 0

[经验分享] 用lua+redis实现一个简单的计数器功能 (二)

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-7-22 08:13:23 | 显示全部楼层 |阅读模式
  环境已经搭建完毕 传送门


  • 计数方案
  就目前来看nginx是最快的服务
  我在设计方案时选择信任redis作为存储库,不做穿透处理,由于目前redis集群方案还不成熟,只在这里做了主备方案。想做集群方案的人可以考虑使用twemproxy
  --如采用twemproxy 集群方案 不要选择信任redis集群,最好有穿透机制 一旦某机器当机,恢复会很麻烦  
  
DSC0000.gif


  • 程序部分
  为方便管理lua文件,修改nginx.conf并重启



lua_package_path '/var/www/lib/?.lua';
lua_package_cpath '/usr/local/nginx/so/?.so'; #加载动态库
init_by_lua_file '/usr/local/nginx/lua/init.lua';#将配置文件加载到nginx内存中
lua_shared_dict config 45m;//配置内存大小
include site/*.conf;

  
  新建site/lua.conf



server {
listen       80;
server_name  count.xxxxxx.com;
location ^~/user_group_praise/ {
                        access_log off;
                        lua_code_cache off;
                        content_by_lua_file /usr/local/nginx/lua/count.lua;
        }
}
  init.lua代码让配置文件常驻内存



local cjson = require "cjson";
local config = ngx.shared.config;
local file = io.open("/usr/local/nginx/lua/count.cjson", "r");
local content = cjson.decode(file:read("*all"));
file:close();
for name, value in pairs(content) do
config:set(name, cjson.encode(value));
end
  count.cjson



{
"user_group_praise": {
"redis_host": "127.0.0.1",
"redis_port": 6379,
"cv_key": "user_praise",
"key": [
"uid"
],
"count_name": "用户直通赞数"
}
}
  
  count.lua代码


DSC0001.gif


ngx.header.content_type = "text/plain;charset=utf-8"
local request_method = ngx.var.request_method
local args = nil
if "GET" == request_method then
args = ngx.req.get_uri_args()
elseif "POST" == request_method then
ngx.req.read_body()
args = ngx.req.get_post_args()
end

local uri = ngx.var.uri;
uri = string.sub(uri,2,#uri);
local uripos = string.find(uri , '/');
if(uripos == null) then
ngx.say('{"errorCode":500,"errorMsg":"'..conf_tab['count_name']..' 参数错误}');
ngx.exit(200);
end
local type = string.sub(uri , 1 ,uripos-1);
local functionname = string.sub(uri , uripos+1 ,#uri);

local cjson = require "cjson";
local config = ngx.shared.config;
local conf_tab = config:get(type);
if(conf_tab == null) then
ngx.say('{"errorCode":500,"errorMsg":"'..conf_tab['count_name']..' 无此计数类型}');
ngx.exit(200);
end
conf_tab = cjson.decode(conf_tab);
local param_key_all = '';
--检测参数
if(functionname  ~= 'get') then
param_key_all = param_key_all..conf_tab['cv_key'];
for key, val in pairs(conf_tab['key']) do
if(args[val] == null) then
ngx.say('{"errorCode":500,"errorMsg":"'..conf_tab['count_name']..' 参数错误}');
ngx.exit(200);
end
param_key_all = param_key_all..':'..args[val];
end
else
if(args['json'] == null) then
ngx.say('{"errorCode":500,"errorMsg":"'..conf_tab['count_name']..' 参数错误}');
ngx.exit(200);
end
local param_tab = cjson.decode(args['json']);
if(param_tab == null) then
ngx.say('{"errorCode":500,"errorMsg":"'..conf_tab['count_name']..' 参数错误}');
ngx.exit(200);
end
for key, val in pairs(param_tab) do
param_key_all = param_key_all..','.."'"..conf_tab['cv_key'];
for i=1,#conf_tab['key'],1 do
if(val[conf_tab['key']] == null) then
ngx.say('{"errorCode":500,"errorMsg":"'..conf_tab['count_name']..' 参数错误}');
ngx.exit(200);
end
param_key_all = param_key_all..':'..val[conf_tab['key']];
end
param_key_all = param_key_all.."'";
end
param_key_all = string.sub(param_key_all,2,#param_key_all);
end
local redis = require("resty.redis");
local red = redis:new();
red:set_timeout(1000); -- 1 sec
local ok, err = red:connect(conf_tab['redis_host'] , conf_tab['redis_port'] );
if not ok then
ngx.say('{"errorCode":500,"errorMsg":"'..conf_tab['count_name']..' REDIS服务器连接错误}')
ngx.exit(200);
end
if(functionname == 'get') then
local cvval = red:eval("return redis.call('mget',"..param_key_all..")",0);
local results = {};
results['data'] = cvval;
results['errorCode'] = 0;
results['errorMsg'] = 'ok';
ngx.say(cjson.encode(results));
elseif(functionname == 'inc') then
cnum=red:incrby(param_key_all,1)
ngx.say('{"errorCode":0,"errorMsg":"ok","data":'..cnum..'}')
elseif(functionname == 'dec') then
cnum=red:incrby(param_key_all,-1);
ngx.say('{"errorCode":0,"errorMsg":"ok","data":'..cnum..'}')
elseif(functionname == 'clear') then
cnum=red:set(param_key_all,0);
ngx.say('{"errorCode":0,"errorMsg":"ok","data":0}')
else
ngx.say('参数错误');
end
red:set_keepalive(0, 100);
View Code   
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-89223-1-1.html 上篇帖子: window平台下安装 redis 下篇帖子: redis学习系列 基本看完
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表