qwzhou89 commented on issue #9920:
URL: https://github.com/apache/apisix/issues/9920#issuecomment-1660336832

   参考github上的代码
   
https://github.com/apache/apisix/blob/4f5ac5870976a26983b9d511c635c51652c6f70f/apisix/debug.lua#L178C1-L178C1
   实现了一个。
   ```yaml
   uri: /test-custome-health-check
   name: test-custome-health-check
   plugins:
     proxy-rewrite:
       uri: /
     serverless-pre-function:
       functions:
         - |
           local core = require('apisix.core');
           local http = require("resty.http")
           local schema = {
             type = 'object',
             required = {'result'},
             properties = {
               result = {
                 pattern = '^0x([0-9a-fA-F]+)$',
                 type = 'string'
               },
               id = {
                 pattern = '^([0-9a-fA-F]+)$',
                 type = 'number'
               }
             }
           }
           local validator = require("jsonschema").generate_validator(schema)
   
           return function(conf, ctx)
             local checker = ctx.up_checker
             core.log.info("checker.run_single_check type is: ",
                     type(checker.run_single_check))
             if type(checker.run_single_check) ~= "function" then
               return
             end
   
             local fun = checker.run_single_check
             local t = {fun_org = fun}
             local mt = {}
             function mt.__call(self, ...)
               local chker, ip, port, hostname, hostheader = 
               select(1, ...), select(2, ...), select(3, ...), select(4, ...), 
select(5, ...)
   
               local headers = {}
               local body = nil
               local m, err
               for _, head in pairs(chker.checks.active.req_headers) do
                 m, err = ngx.re.match(head, [=[^[ ]*([^ ]+):[ ]+(.*)$]=], 
"joi")
                 if err then
                   core.log.error("Head need pre-formatted. ngx.re.match 
failed: ", err)
                   goto continue
                 end
                 if m and string.lower(m[1]) == "body" then
                   body = m[2]
                 else
                   headers[m[1]] = m[2]
                 end
                 core.log.info("healthchecker header: [", m[1], "]: ", m[2])
                 ::continue::
               end
   
               if body then
                 local httpc = http.new()
                 httpc:set_timeout(chker.checks.active.timeout * 1000)
                 local uri = chker.checks.active.type .. "://" .. ip .. ":".. 
port .. chker.checks.active.http_path
                 local res, err = httpc:request_uri(uri,{
                     method = "POST",
                     headers = headers,
                     body = body,
                     ssl_verify = chker.checks.active.https_verify_certificate,
                 })
                 if err ~= nil then
                   core.log.error("healthchecker get response error: ", err)
                   return chker:report_tcp_failure(ip, port, hostname, 
"receive", "active")
                 end
                 if res.status ~= 200 then
                   return chker:report_http_status(ip, port, hostname, 
res.status, "active")
                 end
                 core.log.error(" checker body http: ", res.body)
                 local res_body, err = core.json.decode(res.body)
   
                 if not res_body then
                   core.log.error('failed to decode the req body: ', err)
                   return chker:report_failure(ip, port, hostname, "active")
                 end
   
                 local ok, err = validator(res_body)
                 if not ok then
                   core.log.error("response schema validation failed: ", err)
                   return chker:report_failure(ip, port, hostname, "active")
                 end
                 return chker:report_success(ip, port, hostname, "active")
               else
                 return self.fun_org(...)
               end
             end
             setmetatable(t, mt)
             checker.run_single_check = t
           end
       phase: before_proxy
   upstream:
     nodes:
       - host: 192.168.1.2
         port: 7020
         weight: 1
       - host: 192.168.1.3
         port: 7020
         weight: 1
     retries: 2
     type: roundrobin
     checks:
       active:
         healthy:
           interval: 2
           successes: 1
         http_path: /
         req_headers:
           - 'Content-Type: application/json'
           - 'Body: 
{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":83}'
         timeout: 5
         unhealthy:
           http_failures: 2
           interval: 1
       passive:
         healthy:
           http_statuses:
             - 200
             - 201
           successes: 3
         unhealthy:
           http_failures: 3
           http_statuses:
             - 500
           tcp_failures: 3
   status: 1
   ```


-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to