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 2022/01/25 08:55:03 UTC

[GitHub] [apisix] tzssangglass opened a new issue #6198: bug: core.json cannot serialise table: excessively sparse array if enabled healthcheck

tzssangglass opened a new issue #6198:
URL: https://github.com/apache/apisix/issues/6198


   ### Issue description
   
   When healthcheck is enabled, the checker part of the route or upstream is a sparse array that cannot be serialized by core.json.
   
   ### Environment
   
   - apisix version (cmd: `apisix version`): lasted
   - OS (cmd: `uname -a`):
   - OpenResty / Nginx version (cmd: `nginx -V` or `openresty -V`):
   - etcd version, if have (cmd: run `curl http://127.0.0.1:9090/v1/server_info` to get the info from server-info API):
   - apisix-dashboard version, if have:
   - the plugin runner version, if the issue is about a plugin runner (cmd: depended on the kind of runner):
   - luarocks version, if the issue is about installation (cmd: `luarocks --version`):
   
   
   ### Steps to reproduce
   
   run the test case
   
   ```
   use t::APISIX 'no_plan';
   
   repeat_each(1);
   log_level('info');
   no_root_location();
   no_shuffle();
   worker_connections(256);
   
   run_tests();
   
   __DATA__
   
   === TEST 1: set route(two healthy upstream nodes)
   --- config
       location /t {
           content_by_lua_block {
               local t = require("lib.test_admin").test
               local code, body = t('/apisix/admin/routes/1',
                    ngx.HTTP_PUT,
                    [[{
                       "uri": "/server_port",
                       "upstream": {
                           "type": "roundrobin",
                           "nodes": {
                               "127.0.0.1:1980": 1,
                               "127.0.0.1:1981": 1
                           },
                           "checks": {
                               "active": {
                                   "http_path": "/status",
                                   "host": "foo.com",
                                   "healthy": {
                                       "interval": 1,
                                       "successes": 1
                                   },
                                   "unhealthy": {
                                       "interval": 1,
                                       "http_failures": 2
                                   }
                               }
                           }
                       }
                   }]]
                   )
   
               if code >= 300 then
                   ngx.status = code
               end
               ngx.say(body)
           }
       }
   --- request
   GET /t
   --- response_body
   passed
   --- grep_error_log eval
   qr/^.*?\[error\](?!.*process exiting).*/
   --- grep_error_log_out
   
   
   
   === TEST 2: hit routes (two healthy nodes)
   --- config
       location /t {
           content_by_lua_block {
               ngx.sleep(2) -- wait for sync
   
               local http = require "resty.http"
               local uri = "http://127.0.0.1:" .. ngx.var.server_port
                           .. "/server_port"
   
               local ports_count = {}
               for i = 1, 12 do
                   local httpc = http.new()
                   local res, err = httpc:request_uri(uri, {method = "GET", keepalive = false})
                   if not res then
                       ngx.say(err)
                       return
                   end
                   ports_count[res.body] = (ports_count[res.body] or 0) + 1
               end
   
               local ports_arr = {}
               for port, count in pairs(ports_count) do
                   table.insert(ports_arr, {port = port, count = count})
               end
   
               local function cmd(a, b)
                   return a.port > b.port
               end
               table.sort(ports_arr, cmd)
   
               ngx.say(require("toolkit.json").encode(ports_arr))
               ngx.exit(200)
           }
       }
   --- request
   GET /t
   --- response_body
   [{"count":6,"port":"1981"},{"count":6,"port":"1980"}]
   --- grep_error_log eval
   qr/^.*?\[error\](?!.*process exiting).*/
   --- grep_error_log_out
   --- timeout: 6
   ```
   
   ### Actual result
   
   Only the first request will output `matched route: `. On subsequent requests, `matched route: ` will not be output.
   
   Because the healthcheck is started after the first match, the checker in the route is a sparse array, like
   
   ```
     checker = {
       EVENT_SOURCE = "lua-resty-healthcheck [upstream#/apisix/routes/1]",
       LOG_PREFIX = "[healthcheck] (upstream#/apisix/routes/1) ",
       PERIODIC_LOCK = "lua-resty-healthcheck:upstream#/apisix/routes/1:period_lock:",
       TARGET_COUNTER = "lua-resty-healthcheck:upstream#/apisix/routes/1:counter",
       TARGET_LIST = "lua-resty-healthcheck:upstream#/apisix/routes/1:target_list",
       TARGET_LIST_LOCK = "lua-resty-healthcheck:upstream#/apisix/routes/1:target_list_lock",
       TARGET_LOCK = "lua-resty-healthcheck:upstream#/apisix/routes/1:target_lock",
       TARGET_STATE = "lua-resty-healthcheck:upstream#/apisix/routes/1:state",
       active_check_targets = <function 1>,
       add_target = <function 2>,
       checks = {
         active = {
           concurrency = 10,
           healthy = {
             http_statuses = {
               [200] = true,
               [302] = true
             },
             interval = 1,
             successes = 1
           },
           http_path = "/status",
           https_verify_certificate = true,
           req_headers = { "" },
   ……
   ```
   
   and cannot be encoded by `core.json.delay_encode`, here:
   
   https://github.com/apache/apisix/blob/7f9192576702eb3e5ab4764319756e9d91ab83c9/apisix/init.lua#L400-L401
   
   Trigger conditions for this issue.
   1. healthcheck is enabled.
   2. the log level is info (or even lower)
   3. the object containing the checker (route, upstream) is output in the log with core.json.delay_encode
   
   ### Error log
   
   2022/01/25 16:36:11 [warn] 5573#40074375: *117 [lua] json.lua:82: failed to encode: Cannot serialise table: excessively sparse array force: true, client: 127.0.0.1, server: localhost, request: "GET /server_port HTTP/1.1", host: "127.0.0.1:1984"
   
   
   ### Expected result
   
   no warn level logs


-- 
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



[GitHub] [apisix] tzssangglass commented on issue #6198: bug: core.json cannot serialise sparse array if enabled healthcheck

Posted by GitBox <gi...@apache.org>.
tzssangglass commented on issue #6198:
URL: https://github.com/apache/apisix/issues/6198#issuecomment-1022808748


   It's a bit tricky, the content of the checker is too big……


-- 
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



[GitHub] [apisix] tzssangglass commented on issue #6198: bug: core.json cannot serialise sparse array if enabled healthcheck

Posted by GitBox <gi...@apache.org>.
tzssangglass commented on issue #6198:
URL: https://github.com/apache/apisix/issues/6198#issuecomment-1021308875


   > Is it caused by this part?
   > 
   > ```
   > http_statuses = {
   >             [200] = true,
   >             [302] = true
   > },
   > ```
   > 
   > Since here both the `200` and `302` are numeric.
   
   maybe, if health checks are enabled, the route or upstream must contain a checker, and the checker must contain these.
   
   I think a way to avoid such mistakes is needed.


-- 
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



[GitHub] [apisix] tokers commented on issue #6198: bug: core.json cannot serialise sparse array if enabled healthcheck

Posted by GitBox <gi...@apache.org>.
tokers commented on issue #6198:
URL: https://github.com/apache/apisix/issues/6198#issuecomment-1022868556


   > It's a bit tricky, the content of the checker is too big……
   
   Right, I think estimating the sparse degree is not available.


-- 
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



[GitHub] [apisix] tzssangglass commented on issue #6198: bug: core.json cannot serialise sparse array if enabled healthcheck

Posted by GitBox <gi...@apache.org>.
tzssangglass commented on issue #6198:
URL: https://github.com/apache/apisix/issues/6198#issuecomment-1021308875


   > Is it caused by this part?
   > 
   > ```
   > http_statuses = {
   >             [200] = true,
   >             [302] = true
   > },
   > ```
   > 
   > Since here both the `200` and `302` are numeric.
   
   maybe, if health checks are enabled, the route or upstream must contain a checker, and the checker must contain these.
   
   I think a way to avoid such mistakes is needed.


-- 
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



[GitHub] [apisix] leslie-tsang commented on issue #6198: bug: core.json cannot serialise sparse array if enabled healthcheck

Posted by GitBox <gi...@apache.org>.
leslie-tsang commented on issue #6198:
URL: https://github.com/apache/apisix/issues/6198#issuecomment-1022506920


   Cool, refer to [encode_sparse_array](https://www.kyne.com.au/~mark/software/lua-cjson-manual.html#encode_sparse_array), looks like the `DEFAULT_SPARSE_SAFE` set to `10` is not enough for this scenario.


-- 
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



[GitHub] [apisix] tokers commented on issue #6198: bug: core.json cannot serialise sparse array if enabled healthcheck

Posted by GitBox <gi...@apache.org>.
tokers commented on issue #6198:
URL: https://github.com/apache/apisix/issues/6198#issuecomment-1021759227


   > > Is it caused by this part?
   > > ```
   > > http_statuses = {
   > >             [200] = true,
   > >             [302] = true
   > > },
   > > ```
   > > 
   > > 
   > >     
   > >       
   > >     
   > > 
   > >       
   > >     
   > > 
   > >     
   > >   
   > > Since here both the `200` and `302` are numeric.
   > 
   > maybe, if health checks are enabled, the route or upstream must contain a checker, and the checker must contain these.
   > 
   > I think a way to avoid such mistakes is needed.
   
   Or just use the `encode_sparse_array` method?


-- 
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



[GitHub] [apisix] tokers commented on issue #6198: bug: core.json cannot serialise sparse array if enabled healthcheck

Posted by GitBox <gi...@apache.org>.
tokers commented on issue #6198:
URL: https://github.com/apache/apisix/issues/6198#issuecomment-1021063795


   Is it caused by this part?
   
   ```
   http_statuses = {
               [200] = true,
               [302] = true
   },
   ```
   
   Since here both the `200` and `302` are numeric.


-- 
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



[GitHub] [apisix] tzssangglass commented on issue #6198: bug: core.json cannot serialise sparse array if enabled healthcheck

Posted by GitBox <gi...@apache.org>.
tzssangglass commented on issue #6198:
URL: https://github.com/apache/apisix/issues/6198#issuecomment-1021898686


   > Or just use the `encode_sparse_array` method?
   
   Sounds good, I will try it.


-- 
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



[GitHub] [apisix] starsz commented on issue #6198: bug: core.json cannot serialise sparse array if enabled healthcheck

Posted by GitBox <gi...@apache.org>.
starsz commented on issue #6198:
URL: https://github.com/apache/apisix/issues/6198#issuecomment-1021142014


   > Is it caused by this part?
   > 
   > ```
   > http_statuses = {
   >             [200] = true,
   >             [302] = true
   > },
   > ```
   > 
   > Since here both the `200` and `302` are numeric.
   
   Agree +1. 
   I check it, we don't support encoding if the key is numeric.


-- 
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



[GitHub] [apisix] starsz commented on issue #6198: bug: core.json cannot serialise sparse array if enabled healthcheck

Posted by GitBox <gi...@apache.org>.
starsz commented on issue #6198:
URL: https://github.com/apache/apisix/issues/6198#issuecomment-1021142014


   > Is it caused by this part?
   > 
   > ```
   > http_statuses = {
   >             [200] = true,
   >             [302] = true
   > },
   > ```
   > 
   > Since here both the `200` and `302` are numeric.
   
   Agree +1. 
   I check it, we don't support encoding if the key is numeric.


-- 
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



[GitHub] [apisix] tokers commented on issue #6198: bug: core.json cannot serialise sparse array if enabled healthcheck

Posted by GitBox <gi...@apache.org>.
tokers commented on issue #6198:
URL: https://github.com/apache/apisix/issues/6198#issuecomment-1021063795


   Is it caused by this part?
   
   ```
   http_statuses = {
               [200] = true,
               [302] = true
   },
   ```
   
   Since here both the `200` and `302` are numeric.


-- 
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