【问题标题】:nginx lua redis cookie not settingnginx lua redis cookie未设置
【发布时间】:2013-12-29 23:44:36
【问题描述】:

我正在尝试使用 lua+nginx+redis 设置 cookie。这是我的想法:如果 cookie 不存在,则设置 cookie,然后保存到 redis。

local redis = require "resty.redis"
local red = redis:new()
local md5 = require "md5"

local ip = ngx.var.remote_addr
local secs = ngx.time()
local uid_key = ip .. secs
local uid = md5.sumhexa(uid_key)
local cookie = ngx.var.cookie_uid
local red_cookie = red:hget("cookie:"..uid, uid)

local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
    ngx.say("failed to connect to Redis: ", err)
    return
end

local args = ngx.req.get_headers()
local date_time = ngx.http_time(secs)

if cookie == nil or cookie ~= red_cookie then
    ngx.header['Set-Cookie'] = "path=/; uid=" .. uid
    local res, err = red:hmset("cookie:".. uid,
                               "uid", uid,
                               "date_time", date_time,
                               "user-agent", args["user-agent"]
                               )
    if not res then
        ngx.say("failed to set cookie: ", err)
    end
end

和我的 nginx 配置

...

location /cookie {
    default_type "text/plain";
    lua_code_cache off;
    content_by_lua_file /lua/test.lua;
}

但是,我没有看到 cookie 集。我得到 [错误] 63519#0: *408 在发送响应标头后尝试设置 ngx.header.HEADER,客户端:127.0.0.1,服务器:localhost,请求:“GET /cookie HTTP/1.1”,主机:“localhost "

我似乎无法弄清楚为什么这不起作用?我还认为我可以使用纯 nginx 设置 cookie。我需要跟踪访问我页面的用户。有什么想法吗?

谢谢!!

更新

我修改了从上游访问点发出 redis 请求的想法。现在我不断收到来自 redis.parser 的无效回复。

local redis = require "resty.redis"
local md5 = require "md5"
local parser = require "redis.parser"

local ip = ngx.var.remote_addr
local secs = ngx.time()
local uid_key = ip .. secs
local uid = md5.sumhexa(uid_key)

local args = ngx.req.get_headers()
local date_time = ngx.http_time(secs)

local test_cookie = ngx.location.capture("/redis_check_cookie", {args = {cookie_uid="cookie:"..uid}});
if test_cookie.status ~= 200 or not test_cookie.body then
    ngx.log(ngx.ERR, "failed to query redis")
    ngx.exit(500)
end

local reqs = {
    {"hmset", "cookie:"..uid, "path=/"}
}

local raw_reqs = {}
for i, req in ipairs(reqs) do
    table.insert(raw_reqs, parser.build_query(req))
end

local res = ngx.location.capture("/redis_set_cookie?" .. #reqs,
    { body = table.concat(raw_reqs, "")
    })

local replies = parser.parse_replies(res.body, #reqs)
for i, reply in ipairs(replies) do
    ngx.say(reply[1])
end

我的 nginx 配置文件现在有:

upstream my_redis {
    server 127.0.0.1:6379;
    keepalive 1024 single;
}

    location /redis_check_cookie {
        internal;
        set_unescape_uri $cookie_uid $arg_cookie_uid;
        redis2_query hexists $cookie_uid uid;
        redis2_pass my_redis;
    }

    location /redis_set_cookie {
        internal;
        redis2_raw_queries $args $echo_request_body;
        redis2_pass my_redis;
    }

【问题讨论】:

    标签: nginx lua redis


    【解决方案1】:

    也许你忘了显示一些其他的东西;

    我没有 openresty 环境;但我们的环境是相似的。

    下面的代码是我的测试,运行完美

    这是 nginx.conf

    location /cookie {
        default_type "text/plain";
        lua_code_cache off;
        content_by_lua_file test.lua;
    } 
    

    这是 lua 脚本

    local redis = require "redis"
    local red = redis.connect('192.168.1.51',6379)
    
    local ip = ngx.var.remote_addr
    local secs = ngx.time()
    local uid_key = ip .. secs
    local uid = (uid_key)
    local cookie = ngx.var.cookie_uid
    local red_cookie = red:hget("cookie:"..uid, uid)
    
    
    local args = ngx.req.get_headers()
    local date_time = ngx.http_time(secs)
    
    if cookie == nil or cookie ~= red_cookie then
        ngx.header['Set-Cookie'] = "path=/; uid=" .. uid 
        local res, err = red:hmset("cookie:".. uid,
        "uid", uid, "date_time", date_time,
        "user-agent", args["user-agent"])
    
        if not res then
            ngx.say("failed to set cookie: ", err)
        end 
    end
    

    你会展示更多关于你的代码的信息吗?

    【讨论】:

    • 我认为有一个 ngx.say 被注释掉了,这导致了这个问题。如果我有大量的 http 请求,你对如何处理这样的请求有什么建议吗?我认为打开/关闭redis连接对于每个http请求都不是理想的。
    • @Ptrkcon 可以初始化一个redis池,里面有很多redis连接。然后,你可以从池中获取一个连接,不需要打开和关闭连接。
    • 我是否在更新的代码示例中使用了 redis 池?我也得到 2213#0:当我离开 ngx.var.cookie_uid 时,工作进程 66823 在信号 11 上退出。
    • @Ptrkcon 现在,我对你的问题有点困惑。 1:我不认为你使用redis池,你可以编写另一个脚本来初始化一些redis连接,你可以从池中获取一个连接。2:你可以提供更多关于你的错误的信息,这与redis 池。
    • 很抱歉给您带来了困惑。我也有点失落。我最终要做的是检查用户是否有我设置的cookie(查询我的redis哈希),如果没有,设置一个并将信息发送到redis(新哈希)。所以我想检查 ngx.var.cookie_uid 是否存在。当我将 nix.var.cookie_uid 设置为本地 var 时,我得到了信号 11 上存在工作人员的段错误。问题是我每秒有数千个 http 请求发生,所以我想做上游的 redis 检查,所以我不必须继续打开/关闭我的 redis 连接。
    【解决方案2】:

    朋友们,昨天我用自己的环境,修改了你的一些代码,程序运行正常。

    但是,你说你的代码也很糟糕。

    刚才,我也在用resty.redis。但是代码运行正常。

    所以,我根据你的帖子使用你的环境和你的代码,但是结果还可以。

    我不能再为你提供帮助了。

    【讨论】:

      猜你喜欢
      • 2013-03-28
      • 2020-11-27
      • 2019-01-18
      • 1970-01-01
      • 2015-11-18
      • 2022-06-18
      • 2016-02-13
      • 2016-01-04
      • 2023-03-22
      相关资源
      最近更新 更多