为何无法在init_by_lua阶段使用ngx.socket.tcp()?
PostgreSQL连接报错问题解答
问题描述
我需要从PostgreSQL的Unix socket读取API定义,并将其存入共享字典作为变量。但使用pgmoon库连接PostgreSQL时出现报错,执行代码如下:
local pg = pgmoon.new({ socket_type = "nginx", host = table.concat({"unix:", config.socket}), database = config.database, user = config.user }) assert(pg:connect()) local res = assert(pg:query("select info from testy limit 1")) return res
报错信息:
nginx: [error] init_by_lua_file error: /usr/local/share/lua/5.1/pgmoon/socket.lua:99: no request found stack traceback: [C]: in function 'tcp' /usr/local/share/lua/5.1/pgmoon/socket.lua:99: in function 'new' /usr/local/share/lua/5.1/pgmoon/init.lua:1093: in function '__init' /usr/local/share/lua/5.1/pgmoon/init.lua:1101: in function 'new' ./lua/store.lua:7: in function 'read' .../peter/Documents/resty-engine/src/lua/lifecycle/init.lua:8: in function 'reloadAPI' .../peter/Documents/resty-engine/src/lua/lifecycle/init.lua:16: in main chunk
经测试,直接在init_by_lua_block或文件中执行local socket = ngx.socket.tcp()也会触发相同问题。
原因分析
- 请求上下文缺失:OpenResty的
init_by_lua是nginx启动时的初始化阶段,这个阶段不存在任何请求上下文,而ngx.socket.tcp()属于请求相关API,必须在请求处理阶段(如access_by_lua、content_by_lua等)才能调用,初始化阶段无法提供该API运行所需的环境,因此抛出"no request found"错误。 - 库依赖冲突:pgmoon设置
socket_type = "nginx"时,底层会调用ngx.socket.tcp()创建连接,正好踩中了初始化阶段的API限制。 - 阻塞IO限制:初始化阶段禁止任何阻塞IO操作,数据库连接属于典型的阻塞IO行为,即便绕过socket问题,也会导致nginx启动过程被阻塞甚至失败。
内容的提问来源于stack exchange,提问作者Davam Davac
相关产品推荐
相关产品推荐

