晚上好,再次叨扰,请教一个问题

189 views
Skip to first unread message

jiangfei

unread,
May 26, 2012, 9:53:38 AM5/26/12
to openresty, age...@gmail.com
大家晚上好,我叫江飞,刚刚接触openresty,遇到点问题,请教一下
我把lua table通过cjson序列化为json串然后,用HttpMemcModule往memcached中保存,
取出来后发现,把[, { ,",:等都给转义了,没办法反序列化成lua table了,请教下有没有解决办法?

agentzh

unread,
May 26, 2012, 9:55:12 AM5/26/12
to jiangfei, openresty
2012/5/26 jiangfei <liujiang...@gmail.com>:

> 大家晚上好,我叫江飞,刚刚接触openresty,遇到点问题,请教一下
> 我把lua table通过cjson序列化为json串然后,用HttpMemcModule往memcached中保存,
> 取出来后发现,把[, { ,",:等都给转义了,没办法反序列化成lua table了,请教下有没有解决办法?

请给出你使用的 Lua 代码和 nginx 配置文件 :) 尽量是最小化的例子哈。

Regards,
-agentzh

jiangfei

unread,
May 26, 2012, 10:27:13 AM5/26/12
to openresty
好的,谢谢春哥,下面是我的最小化代码
nginx.conf
-----------------------------------
worker_processes 1;
error_log logs/error.log;
events {
worker_connections 1024;
}
http {

upstream memc_pool {
server 127.0.0.1:11211;
keepalive 1024 single;
}

server {
listen 8080;

#memcache interface
location = /memc {
#internal;
set $memc_cmd $arg_cmd;
set $memc_key $arg_key;
set $memc_value $arg_val;
set $memc_exptime $arg_exptime;

memc_pass '127.0.0.1:11211';
#memc_pass memc_pool;
}

#proccess push
location ~ ^.*/(infor_push.action|push_push.do)$ {
lua_code_cache off;
content_by_lua_file 'lua/push.lua';
}
}
}
--------------------------------------------
--push.lua
--------------------------------------------
local cjson = require "cjson"

local testable = {{name="divad",sex="man"},
{name="xiaobao",sex="girl"}}
local strtable = cjson.encode(testable)
ngx.location.capture("/memc", {
args={cmd="set",key="foo",val=strtable}

})
local strt = ngx.location.capture("/memc", {
args={cmd="get",key="foo"}
})
--local test = cjson.decode(strt.body)
ngx.say(strtable)
ngx.say(strt.body)

下面是浏览器输出:
[{"name":"divad","sex":"man"},{"name":"xiaobao","sex":"girl"}]
%5b%7b%22name%22%3a%22divad%22,%22sex%22%3a%22man%22%7d,%7b%22name
%22%3a%22xiaobao%22,%22sex%22%3a%22girl%22%7d%5d

On 5月26日, 下午9时55分, agentzh <agen...@gmail.com> wrote:
> 2012/5/26 jiangfei <liujiangfei.di...@gmail.com>:

agentzh

unread,
May 26, 2012, 12:13:02 PM5/26/12
to open...@googlegroups.com
Hello!

2012/5/26 jiangfei <liujiang...@gmail.com>:
[...]


> #memcache interface
> location = /memc {
> #internal;
> set $memc_cmd $arg_cmd;
> set $memc_key $arg_key;
> set $memc_value $arg_val;
> set $memc_exptime $arg_exptime;
>

这里 $arg_XXX 变量的值都是未经过 URI 反转义的,所以里面都是 %XX 这样的东西。你应该在这里使用
set_unescape_uri 配置指令先对 $arg_XXX 变量进行反转义,即:

set_unescape_uri $memc_cmd $arg_cmd;
set_unescape_uri $memc_key $arg_key;
set_unescape_uri $memc_value $arg_val;
set_unescape_uri $memc_exptime $arg_exptime;

更多细节可以参见 ngx_set_misc 模块的 set_unescape_uri 指令的文档:

http://wiki.nginx.org/HttpSetMiscModule#set_unescape_uri

还有我的"Nginx 变量漫谈"系列的 nginx 教程:

http://agentzh.org/misc/nginx/agentzh-nginx-tutorials-zhcn.html#01-NginxVariables02

> memc_pass '127.0.0.1:11211';
> #memc_pass memc_pool;
> }
>

[...]


> ngx.location.capture("/memc", {
> args={cmd="set",key="foo",val=strtable}
>
> })

这里 ngx.location.capture 的 args 选项会自动对 cmd, key, val 这三个参数的值进行 URI
转义。所以你需要在 location /memc 中进行反转义,以还原原始的值。

关于 ngx.location.capture 的此行为的更多细节请参见官方文档:

http://wiki.nginx.org/HttpLuaModule#ngx.location.capture

>
> 下面是浏览器输出:
> [{"name":"divad","sex":"man"},{"name":"xiaobao","sex":"girl"}]
> %5b%7b%22name%22%3a%22divad%22,%22sex%22%3a%22man%22%7d,%7b%22name
> %22%3a%22xiaobao%22,%22sex%22%3a%22girl%22%7d%5d
>

这里的输出证实了你未在 location /memc 中对 $arg_val 等变量的值进行 URI 反转义的错误。

另外,值得一提的是,推荐使用 lua-resty-memcached 库来从 Lua 访问 memcached 后端:

https://github.com/agentzh/lua-resty-memcached

这比你当前所使用的 ngx.location.capture + ngx_memc 的方式更为简单高效。

Regards,
-agentzh

jiangfei

unread,
May 26, 2012, 12:54:21 PM5/26/12
to openresty
这么晚还没休息,我昨天看到第变量第5讲,现在也在看,刚好还没看到关键点,我今天晚上好好把你的系列消化下,
谢谢春哥,如果你有时间来上海,我一定请你吃顿饭,先拜谢了

On 5月27日, 上午12时13分, agentzh <agen...@gmail.com> wrote:
> Hello!
>
> 2012/5/26 jiangfei <liujiangfei.di...@gmail.com>:


> [...]
>
> > #memcache interface
> > location = /memc {
> > #internal;
> > set $memc_cmd $arg_cmd;
> > set $memc_key $arg_key;
> > set $memc_value $arg_val;
> > set $memc_exptime $arg_exptime;
>
> 这里 $arg_XXX 变量的值都是未经过 URI 反转义的,所以里面都是 %XX 这样的东西。你应该在这里使用
> set_unescape_uri 配置指令先对 $arg_XXX 变量进行反转义,即:
>
> set_unescape_uri $memc_cmd $arg_cmd;
> set_unescape_uri $memc_key $arg_key;
> set_unescape_uri $memc_value $arg_val;
> set_unescape_uri $memc_exptime $arg_exptime;
>
> 更多细节可以参见 ngx_set_misc 模块的 set_unescape_uri 指令的文档:
>
> http://wiki.nginx.org/HttpSetMiscModule#set_unescape_uri
>
> 还有我的"Nginx 变量漫谈"系列的 nginx 教程:
>

> http://agentzh.org/misc/nginx/agentzh-nginx-tutorials-zhcn.html#01-Ng...

jiangfei

unread,
May 26, 2012, 1:09:44 PM5/26/12
to openresty
谢谢亦春哥,你的回复价值很高,信息量很大,resty-memcached确实好用..

On 5月27日, 上午12时13分, agentzh <agen...@gmail.com> wrote:
> Hello!
>
> 2012/5/26 jiangfei <liujiangfei.di...@gmail.com>:

> [...]
>
> > #memcache interface
> > location = /memc {
> > #internal;
> > set $memc_cmd $arg_cmd;
> > set $memc_key $arg_key;
> > set $memc_value $arg_val;
> > set $memc_exptime $arg_exptime;
>
> 这里 $arg_XXX 变量的值都是未经过 URI 反转义的,所以里面都是 %XX 这样的东西。你应该在这里使用
> set_unescape_uri 配置指令先对 $arg_XXX 变量进行反转义,即:
>
> set_unescape_uri $memc_cmd $arg_cmd;
> set_unescape_uri $memc_key $arg_key;
> set_unescape_uri $memc_value $arg_val;
> set_unescape_uri $memc_exptime $arg_exptime;
>
> 更多细节可以参见 ngx_set_misc 模块的 set_unescape_uri 指令的文档:
>
> http://wiki.nginx.org/HttpSetMiscModule#set_unescape_uri
>
> 还有我的"Nginx 变量漫谈"系列的 nginx 教程:
>

> http://agentzh.org/misc/nginx/agentzh-nginx-tutorials-zhcn.html#01-Ng...

pengqi

unread,
May 26, 2012, 9:10:11 PM5/26/12
to open...@googlegroups.com
使用 lua-resty-memcached 库访问 memcached 后端,比使用的 ngx.location.capture + ngx_memc 的方式更高效吗?我的理解是后者更为高效吧,后者毕竟是c级别的




--
Jinglong
Software Engineer
Server Platforms Team at Taobao

jiangfei

unread,
May 26, 2012, 10:33:41 PM5/26/12
to openresty
这个不好说,capture多跑了一趟请求流程,等春哥解答吧

On 5月27日, 上午9时10分, pengqi <fengm...@gmail.com> wrote:
> 使用 lua-resty-memcached 库访问 memcached 后端,比使用的 ngx.location.capture +
> ngx_memc 的方式更高效吗?我的理解是后者更为高效吧,后者毕竟是c级别的
>

> > 建议: 提问的智慧http://wiki.woodpecker.org.cn/moin/AskForHelp

xiaoxi mou

unread,
Sep 18, 2016, 10:51:59 PM9/18/16
to openresty
hi 春哥 您好,想请教一下

我用 set_unescape_uri $output_xxx $arg_xxx;
对$arg_XXX 变量进行反转义, 然后更具如下方式输出到日志里

 log_format  resjson  '{ "@timestamp":"$time_iso8601",'
                      '"request":"$output_xxx",'
                      '"upstream_response_time":"$upstream_response_time"}';

配合 log_escape_non_ascii off 就可以在日志里打出 中文, 这样方便我们后续对日志的分析

可是   set_unescape_uri 的 context 是 location, location if

想问一下  set_unescape_uri 是否额可以 像 set  一样 可以在 server  中 应用, 这样将  output_xxx设置 成全局的 不用在 每一个 location中 使用 set_unescape_uri
直接使用 access_log access.log  resjson ,将每一个location 的日志 以同样的格式输出到日志中 

我将 set_unescape_uri 在 context  为  server  中 使用了 ,测试 确实可以。

您在 文档 中 注明了  set_unescape_uri 的  context 是 location, location if ,我这样使用 是否有什么隐患,或者有其他什么好的方式解决.....
期待您的回复 ,谢谢


在 2012年5月27日星期日 UTC+8上午12:13:02,agentzh写道:
Reply all
Reply to author
Forward
0 new messages