Hello!
2014-03-17 19:19 GMT-07:00 n4mine:
> 回复内容见下文,应该是这么引用和回复的。
请在引用原文时不要引用过长的文字;原则上不应超过 10 行。
>
> 这里我的写法如下:
> ngx.log(ngx.ERR,[[|\tupstrem_response_time:]]..ngx.var.upstream_response_time..[[\tupstream_addr:]]..ngx.var.upstream_addr.."\t|")
你这里的一个问题是不应直接用 .. 拼接可能为 nil 的值。比如这里的 ngx.var.xxx 的值就可能为 nil. 而当拼接 nil
值时会抛出运行时错误:
$ luajit -e 'print("a" .. nil)'
luajit: (command line):1: attempt to concatenate a nil value
stack traceback:
(command line):1: in main chunk
[C]: at 0x00404e80
你应该按我的写法,把可能为 nil 的值直接作为 ngx.log() 函数的独立的参数。
>
> nil值,我试过了,没有生效
> 我使用空字符串来试验一下。
我很奇怪你为什么不使用最简单的例子进行测试。毕竟你直接在很复杂的配置里试验时很可能因为别的错误会让你得到错误的结论。
考虑下面这个最小化的例子:
location = /t {
access_by_lua '
return ngx.exit(503)
';
log_by_lua '
if ngx.var.upstream_addr == nil then
ngx.log(ngx.ERR, "upstream addr is nil!")
end
ngx.log(ngx.ERR, "upstream addr: ", ngx.var.upstream_addr)
';
proxy_pass http://foo.com;
}
在这个例子里,我们在 access_by_lua 里提前终止当前请求,并使用 503 错误码,从而 proxy_pass
根本不会有机会运行。这个例子很好地摸拟了 ngx_limit_req 模块拒绝当前请求的情形。用 curl 之类的 http
客户端访问一下这个 /t 接口,便会在 error.log 文件中得到下面这 2 条消息:
[error] 30599#0: *1 [lua] log_by_lua:3: upstream addr is nil!
while logging request
[error] 30544#0: *1 [lua] log_by_lua:2: error: nil while logging request ...
我们看到此种情况下,ngx.var.upstream_addr 的值确实为 nil.
> 上述代码,写的我逻辑一度混乱。 !-_-
请按照我上面演示的那样,尽量通过最简单的例子来验证你的猜测,不要在还没把基本问题搞清楚时,就在真实的配置里胡子辫子一把抓。那样搞,即使是神仙也会混乱的 :)
作为工程师,很重要的一点就是要有足够的耐心。否则很可能不仅浪费你自己的时间,还会浪费别人的时间 :)
Regards,
-agentzh