分发层架构中,我们会在nginx里去写lua脚本,因为我们需要自定义一些特殊的业务逻辑
比如说,流量分发,自己用lua去写分发的逻辑,在分发层nginx里去写的
再比如说,要用l缓存架构中的的控制逻辑,在应用层nginx里去写的
nginx+lua 用最流行的开源方案,就是用OpenResty
这次我下了一个最新的OpenResty,自己用lua去写分发的逻辑,在分发层nginx里去写的,发现OpenResty最新的 http.new() new出来的对象request_uri方法老是报错,原来一直都是这样就可以的
local resp, err = httpc:request_uri(hostUrl, {
method = “GET”,
path = requestBody
})
结果居然报错了,提示
lua entry thread aborted: runtime error: /usr/hello/lualib/resty/http.lua:909: bad argument #2 to ‘set_keepalive’ (number expected, got nil)
以前做类似的分发代码的时候,request_uri方法是从来不会报错的,反复检查自己代码很多遍,应该没问题才是,然后直接去看http.lua源码了,来到909行
在 909 local ok, err = self:set_keepalive(params.keepalive_timeout, params.keepalive_pool)直接报错
提示bad argument 分析以上代码
看
902 if params.keepalive == false then
903 local ok, err = self:close()
904 if not ok then
905 ngx_log(ngx_ERR, err)
906 end
分析说明:
若params 也就是之前我们请求时带的关联数组
{
method = “GET”,
path = requestBody
} 这一坨中keepalive这个属性不为假 那就调用self:set_keepalive方法,然后这方法调用失败了,因为我们没有在params传参数进去
直接报number expected, got nil,参数为空
不知道大家有没有发现什么问题,其实是OpenResty源码这一块有问题,他不应该去判断是否keepalive为假,因为keepalive这个参数不填的时候,lua的语言性质决定了,这个地方会返回假 因为nil == false会返回假 所以就执行了有keepalive的逻辑 不信的同学可以用lua交互式模式打印一下 print(nil == false) 会返回假的 所以本来空值的时候不该走下面的流程的,但是由于编码疏忽,没有实现相应的效果
希望OpenResty官方尽快修复这个错误
临时解决方案:
在关联数组中多传一个参数keepalive=false 即
{
method = “GET”,
path = requestBody,
keepalive=false
}
显式的给keepalive传递一个false 避免发生这样的问题******