You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by GitBox <gi...@apache.org> on 2021/11/10 08:28:12 UTC
[GitHub] [apisix] chzhuo commented on issue #4077: passive healthcheck not working after configuration changing
chzhuo commented on issue #4077:
URL: https://github.com/apache/apisix/issues/4077#issuecomment-964890775
> @Ben0625 Could you try the `2.5` version? And test it whether it can be reproduced in `2.5`?
We get the same problems on the apisix 2.8
I found a bug in https://github.com/api7/lua-resty-healthcheck/blob/master/lib/resty/healthcheck.lua
The content of var `defaults` will be modified when not assigned the passive or active config item
Reproduce the bug:
nginx.conf
```lua
daemon off;
worker_processes 1;
error_log stderr;
events {
worker_connections 1024;
}
http {
access_log off;
server {
listen 19000;
location / {
default_type text/html;
content_by_lua '
ngx.say("<p>Hello, World!</p>")
';
log_by_lua '
local check = require("check")
';
}
}
}
```
check.lua
```lua
local cjson = require("cjson.safe")
-- copy from: https://github.com/api7/lua-resty-healthcheck/blob/master/lib/resty/healthcheck.lua#L1162
--============================================================================
-- Create health-checkers
--============================================================================
local NO_DEFAULT = {}
local MAXNUM = 2^31 - 1
local function fail(ctx, k, msg)
ctx[#ctx + 1] = k
error(table.concat(ctx, ".") .. ": " .. msg, #ctx + 1)
end
local function fill_in_settings(opts, defaults, ctx)
ctx = ctx or {}
local obj = {}
for k, default in pairs(defaults) do
local v = opts[k]
-- basic type-check of configuration
if default ~= NO_DEFAULT
and v ~= nil
and type(v) ~= type(default) then
fail(ctx, k, "invalid value")
end
if v ~= nil then
if type(v) == "table" then
if default[1] then -- do not recurse on arrays
obj[k] = v
else
ctx[#ctx + 1] = k
obj[k] = fill_in_settings(v, default, ctx)
ctx[#ctx + 1] = nil
end
else
if type(v) == "number" and (v < 0 or v > MAXNUM) then
fail(ctx, k, "must be between 0 and " .. MAXNUM)
end
obj[k] = v
end
elseif default ~= NO_DEFAULT then
obj[k] = default
end
end
return obj
end
local defaults = {
name = NO_DEFAULT,
shm_name = NO_DEFAULT,
type = NO_DEFAULT,
status_ver = 0,
checks = {
active = {
type = "http",
timeout = 1,
concurrency = 10,
http_path = "/",
https_verify_certificate = true,
healthy = {
interval = 0, -- 0 = disabled by default
http_statuses = { 200, 302 },
successes = 2,
},
unhealthy = {
interval = 0, -- 0 = disabled by default
http_statuses = { 429, 404,
500, 501, 502, 503, 504, 505 },
tcp_failures = 2,
timeouts = 3,
http_failures = 5,
},
req_headers = {""},
},
passive = {
type = "http",
healthy = {
http_statuses = { 200, 201, 202, 203, 204, 205, 206, 207, 208, 226,
300, 301, 302, 303, 304, 305, 306, 307, 308 },
successes = 5,
},
unhealthy = {
http_statuses = { 429, 500, 503 },
tcp_failures = 2,
timeouts = 7,
http_failures = 5,
},
},
},
}
local function to_set(tbl, key)
local set = {}
for _, item in ipairs(tbl[key]) do
set[item] = true
end
tbl[key] = set
end
-- In the below is my code
local option_no_passive = cjson.decode([[
{
"checks":
{
"active":{"unhealthy":{"tcp_Failures":3,"http_statuses":[500,501,502,503,504,505],"timeouts":3,"interval":100,"tcp_failures":2,"http_failures":3},"concurrency":10,"http_path":"\/healthz","https_verify_certificate":true,"port":9080,"type":"http","healthy":{"interval":5,"successes":1,"http_statuses":[200,201,202,203,204,205,206,207,208,226,300,301,302,303,304,305,306,307,308,400,401,403,404,405,415,429]},"host":"healthcheck","timeout":5}
},
"name":"upstream#\/internal-apisix\/upstreams\/380542682478412600","shm_name":"upstream-healthcheck"
}]])
-- The default can be encoded to json
ngx.log(ngx.ERR, "===defaults: ", cjson.encode(defaults))
-- The default `passive` config will be filled into `filled_option_no_passive` by the method `fill_in_settings`
local filled_option_no_passive = fill_in_settings(option_no_passive ,defaults)
ngx.log(ngx.ERR, "===filled_option_no_passive: ", cjson.encode(filled_option_no_passive))
-- copy from: https://github.com/api7/lua-resty-healthcheck/blob/master/lib/resty/healthcheck.lua#L1364
to_set(filled_option_no_passive.checks.active.unhealthy, "http_statuses")
to_set(filled_option_no_passive.checks.active.healthy, "http_statuses")
to_set(filled_option_no_passive.checks.passive.unhealthy, "http_statuses")
to_set(filled_option_no_passive.checks.passive.healthy, "http_statuses")
-- print: nil Cannot serialise table: excessively sparse array while logging request
-- The defaults has been modified by `to_set`
ngx.log(ngx.ERR, "===defaults: ", cjson.encode(defaults))
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@apisix.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org