Closed SvenAlHamad closed 6 years ago
@SvenAlHamad Nonblocking means not blocking any OS threads. This library's API is nonblocking but synchronous, meaning that the current request will not continue without waiting for the MySQL replies.
Hmm...but in that case I'm not sure why my code doesn't work:
code-to-set-target.lua;
local mysql = require "resty.mysql"
local db, err = mysql:new()
if not db then
ngx.say("failed to instantiate mysql: ", err)
return
end
db:set_timeout(1000) -- 1 sec
local ok, err, errcode, sqlstate = db:connect{
host = "----",
port = 3306,
database = "proxy",
user = "----",
password = "-----",
charset = "utf8",
max_packet_size = 1024 * 1024,
}
if not ok then
ngx.say("failed to connect: ", err, ": ", errcode, " ", sqlstate)
return
end
--ngx.say("connected to mysql.")
local quoted_name = ngx.quote_sql_str(ngx.var.host)
res, err, errcode, sqlstate = db:query("select target from domains where domain = " .. quoted_name, 1)
if not res then
ngx.say("bad result: ", err, ": ", errcode, ": ", sqlstate, ".")
return
end
local cjson = require "cjson"
--ngx.say("result: ", cjson.encode(res))
local temp = res[1].target
--ngx.say("temp: ", temp)
ngx.var.target = temp
--ngx.say("ngx var: ", ngx.var.target)
local ok, err = db:set_keepalive(10000, 100)
if not ok then
ngx.say("failed to set keepalive: ", err)
return
end
When I uncomment the ngx.say
calls, I get an output with the correct values.
But then inside my nginx.conf
file, the proxy pass $target
value seems to be empty.
In case I manually set a hardcoded value for ngx.var.target
inside the lua script, that value is passed correctly to the nginx.conf
. That's why I thought it's got something to do with the non-blocking nature.
This is the extract from the nginx.conf
.
location / {
set $target;
rewrite_by_lua_file /etc/openresty/scripts/code-to-set-target.lua;
# proxy
proxy_pass https://$host$target;
}
@SvenAlHamad You cannot use ngx.say()
to generate a response in the rewrite phase otherwise your proxy_pass
won't have a chance to generate its own response.
@SvenAlHamad For debugging purposes, you should use ngx.log()
or print()
instead.
@agentzh thanks for the tip!
I've used ngx.say
just for testing. But even if replace all the instances of that call with print
, I get exactly the same behavior as before. My variable is still not populated, but in the logs, I see the print
entries with the correct values. However, I've then tried outputting the value of the $target
like so, and I get back an empty response:
nginx.conf
location / {
set $target;
rewrite_by_lua_file /etc/openresty/scripts/code-to-set-target.lua;
return 200 $target;
}
Have any ideas why that might be?
@SvenAlHamad return
directive runs before rewrite_by_lua_file
no matter how you arrange them in nginx.conf
. I suggest you read my tutorials first to be aware of such pitfalls:
https://openresty.org/download/agentzh-nginx-tutorials-en.html
Hi,
I'm trying to create a reverse proxy, where the upstream location is defined inside a mysql table. I'm using this module to fetch the target, however I'm having a problem since this module works in a non-blocking mode.
Imagine this code:
$target
is always empty when executing the proxy_pass line, but actually the problem is that the variable inside the lua scripts is populated only when the mysql result is returned, which can happen after the proxy_pass line is executed.My question is, how can I force the mysql module to wait until results are returned, before proceeding with the rest of the execution?