LEN

Nginx Redis Lua 模块试用体验
使用场景:基于Nginx的redis2模块 使用redis统计接口每秒请求数量. upstream redi...
扫描右侧二维码阅读全文
03
2017/05

Nginx Redis Lua 模块试用体验

使用场景:

基于Nginx的redis2模块 使用redis统计接口每秒请求数量.

    upstream redis {
        server 127.0.0.1:6397;
        keepalive 16;
    }

    location ~ \.php {
        set $redis_key 'test_list';
        redis2_pass     $redis;
        redis2_query zadd $redis_key 1 $request_uri;
    
        fastcgi_pass  unix:/dev/shm/php-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_split_path_info ^(.+\.php)(.*)$;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

直接使用 redis2-nginx-module 模块问题很多.
上面的nginx location 配置 只能是二选一 要么输出php 要么就返回redis2_query的结果;
经过昨天一天的测试,得出的结论: 单独使用redis2模块仅适合 打点类场景,不在乎返回值的场景.

为了满足需求,改用 lua + redis2 两个模块组合使用:

    http {
        include       mime.types;
        default_type  application/octet-stream;
        #日志格式
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
        # 引入lua redis 模块
        lua_package_path "/usr/local/nginx/lua-resty-redis-0.26/lib/?.lua;;";
        ...

    location ~ \.php {
        fastcgi_pass  unix:/dev/shm/php-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_split_path_info ^(.+\.php)(.*)$;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    
        default_type text/html;
        lua_code_cache on;
        rewrite_by_lua_file /usr/local/nginx/lua/test_redis_basic.lua;
    }

Lua : /usr/local/nginx/lua/test_redis_basic.lua

    -- 接受Nginx传递进来的参数$1 也就是SteamName
    local uri = ngx.var.request_uri
    local redis = require("resty.redis");

    -- 创建一个redis对象实例。在失败,返回nil和描述错误的字符串的情况下
    local redis_instance = redis:new();

    -- 设置后续操作的超时(以毫秒为单位)保护,包括connect方法
    redis_instance:set_timeout(1000)

    -- 建立连接
    local ip = '127.0.0.1'
    local port = 6397

    -- 尝试连接到redis服务器正在侦听的远程主机和端口
    local ok,err = redis_instance:connect(ip,port)
    if not ok then
        ngx.say("connect redis error : ", err)
        return err
    end

    -- 选择数据库
    redis_instance:select(0)

    -- URI请求数量时间到秒
    local reshincr, err = redis_instance:hincrby('request:second:'..uri, os.time(), 1)
    if not reshincr then
        ngx.say("request:second error: ", err)
        return err
    end

上面使用 lua 嵌套入nginx 中调用redis 着实给力

1493810514.857005 [0 127.0.0.1:56570] "select" "0"
1493810514.857278 [0 127.0.0.1:56570] "hincrby" "request:second:/%E6%88%91%E6%98%AF%E4%B8%80%E4%B8%AA%E7%BA%BF%E7%A8%8B/" "1493810514" "1"
1493810515.245194 [0 127.0.0.1:56578] "select" "0"
1493810515.245363 [0 127.0.0.1:56578] "hincrby" "request:second:/%E6%88%91%E6%98%AF%E4%B8%80%E4%B8%AA%E7%BA%BF%E7%A8%8B/" "1493810515" "1"
1493810525.126006 [0 127.0.0.1:56581] "select" "0"
1493810525.126191 [0 127.0.0.1:56581] "hincrby" "request:second:/" "1493810525" "1"
1493810527.514504 [0 127.0.0.1:56583] "select" "0"
1493810527.514667 [0 127.0.0.1:56583] "hincrby" "request:second:/" "1493810527" "1"
1493810534.341694 [0 127.0.0.1:56589] "select" "0"

统计写入成功, 上面的location配置中 rewrite_by_lua_file 需要放置最后
技术难点已解决,剩下的都是小问题了.

最后修改:2017 年 05 月 03 日 08 : 06 PM
如果觉得我的文章对你有用,请随意赞赏

发表评论