You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by sp...@apache.org on 2022/03/08 05:53:52 UTC

[apisix] branch release/2.10 updated: change: backport server-info to 2.10 (#6509)

This is an automated email from the ASF dual-hosted git repository.

spacewander pushed a commit to branch release/2.10
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/release/2.10 by this push:
     new 60987be  change: backport server-info to 2.10 (#6509)
60987be is described below

commit 60987be3a38295a4e2462442dd7c33f782a2b525
Author: Yu.Bozhong <y....@foxmail.com>
AuthorDate: Tue Mar 8 13:53:46 2022 +0800

    change: backport server-info to 2.10 (#6509)
---
 apisix/core/etcd.lua                  | 16 ++++++
 apisix/plugins/server-info.lua        | 96 ++++++++++++++++++++++++++---------
 conf/config-default.yaml              |  3 +-
 docs/en/latest/plugins/server-info.md | 12 ++---
 docs/zh/latest/plugins/server-info.md | 23 +++------
 t/plugin/server-info.t                | 72 +++++++-------------------
 6 files changed, 119 insertions(+), 103 deletions(-)

diff --git a/apisix/core/etcd.lua b/apisix/core/etcd.lua
index 1375470..55efb2c 100644
--- a/apisix/core/etcd.lua
+++ b/apisix/core/etcd.lua
@@ -207,6 +207,7 @@ local function set(key, value, ttl)
             return nil, grant_err
         end
         res, err = etcd_cli:set(prefix .. key, value, {prev_kv = true, lease = data.body.ID})
+        res.body.lease_id = data.body.ID
     else
         res, err = etcd_cli:set(prefix .. key, value, {prev_kv = true})
     end
@@ -360,4 +361,19 @@ function _M.server_version()
 end
 
 
+function _M.keepalive(id)
+    local etcd_cli, _, err = new()
+    if not etcd_cli then
+        return nil, err
+    end
+
+    local res, err = etcd_cli:keepalive(id)
+    if not res then
+        return nil, err
+    end
+
+    return res
+end
+
+
 return _M
diff --git a/apisix/plugins/server-info.lua b/apisix/plugins/server-info.lua
index 91ee347..055bafa 100644
--- a/apisix/plugins/server-info.lua
+++ b/apisix/plugins/server-info.lua
@@ -26,8 +26,8 @@ local type = type
 
 local load_time = os.time()
 local plugin_name = "server-info"
-local default_report_interval = 60
-local default_report_ttl = 7200
+local default_report_ttl = 60
+local lease_id
 
 local schema = {
     type = "object",
@@ -35,18 +35,11 @@ local schema = {
 local attr_schema = {
     type = "object",
     properties = {
-        report_interval = {
-            type = "integer",
-            description = "server info reporting interval (unit: second)",
-            default = default_report_interval,
-            minimum = 60,
-            maximum = 3600,
-        },
         report_ttl = {
             type = "integer",
             description = "live time for server info in etcd",
             default = default_report_ttl,
-            minimum = 3600,
+            minimum = 3,
             maximum = 86400,
         }
     }
@@ -94,9 +87,7 @@ local function uninitialized_server_info()
         hostname         = core.utils.gethostname(),
         id               = core.id.get(),
         version          = core.version.VERSION,
-        up_time          = ngx_time() - boot_time,
         boot_time        = boot_time,
-        last_report_time = -1,
     }
 end
 
@@ -104,6 +95,7 @@ end
 local function get()
     local data, err = internal_status:get("server_info")
     if err ~= nil then
+        core.log.error("get error: ", err)
         return nil, err
     end
 
@@ -113,10 +105,10 @@ local function get()
 
     local server_info, err = core.json.decode(data)
     if not server_info then
+        core.log.error("failed to decode server_info: ", err)
         return nil, err
     end
 
-    server_info.up_time = ngx_time() - server_info.boot_time
     return server_info
 end
 
@@ -132,11 +124,37 @@ local function get_server_info()
 end
 
 
+local function set(key, value, ttl)
+    local res_new, err = core.etcd.set(key, value, ttl)
+    if not res_new then
+        core.log.error("failed to set server_info: ", err)
+        return nil, err
+    end
+
+    if not res_new.body.lease_id then
+        core.log.error("failed to get lease_id: ", err)
+        return nil, err
+    end
+
+    lease_id = res_new.body.lease_id
+
+    -- set or update lease_id
+    local ok, err = internal_status:set("lease_id", lease_id)
+    if not ok then
+        core.log.error("failed to set lease_id to shdict: ", err)
+        return nil, err
+    end
+
+    return true
+end
+
+
 local function report(premature, report_ttl)
     if premature then
         return
     end
 
+    -- get apisix node info
     local server_info, err = get()
     if not server_info then
         core.log.error("failed to get server_info: ", err)
@@ -158,12 +176,47 @@ local function report(premature, report_ttl)
         end
     end
 
-    server_info.last_report_time = ngx_time()
-
+    -- get inside etcd data, if not exist, create it
     local key = "/data_plane/server_info/" .. server_info.id
-    local ok, err = core.etcd.set(key, server_info, report_ttl)
+    local res, err = core.etcd.get(key)
+    if not res or (res.status ~= 200 and res.status ~= 404) then
+        core.log.error("failed to get server_info from etcd: ", err)
+        return
+    end
+
+    if not res.body.node then
+        local ok, err = set(key, server_info, report_ttl)
+        if not ok then
+            core.log.error("failed to set server_info to etcd: ", err)
+            return
+        end
+
+        return
+    end
+
+    local ok = core.table.deep_eq(server_info, res.body.node.value)
+    -- not equal, update it
     if not ok then
-        core.log.error("failed to report server info to etcd: ", err)
+        local ok, err = set(key, server_info, report_ttl)
+        if not ok then
+            core.log.error("failed to set server_info to etcd: ", err)
+            return
+        end
+
+        return
+    end
+
+    -- get lease_id from ngx dict
+    lease_id, err = internal_status:get("lease_id")
+    if not lease_id then
+        core.log.error("failed to get lease_id from shdict: ", err)
+        return
+    end
+
+    -- call keepalive
+    local res, err = core.etcd.keepalive(lease_id)
+    if not res then
+        core.log.error("send heartbeat failed: ", err)
         return
     end
 
@@ -203,8 +256,6 @@ end
 
 
 function _M.init()
-    core.log.info("server info: ", core.json.delay_encode(get()))
-
     if core.config ~= require("apisix.core.config_etcd") then
         -- we don't need to report server info if etcd is not in use.
         return
@@ -218,12 +269,12 @@ function _M.init()
     end
 
     local report_ttl = attr and attr.report_ttl or default_report_ttl
-    local report_interval = attr and attr.report_interval or default_report_interval
     local start_at = ngx_time()
 
     local fn = function()
         local now = ngx_time()
-        if now - start_at >= report_interval then
+        -- If ttl remaining time is less than half, then flush the ttl
+        if now - start_at >= (report_ttl / 2) then
             start_at = now
             report(nil, report_ttl)
         end
@@ -239,8 +290,7 @@ function _M.init()
 
     timers.register_timer("plugin#server-info", fn, true)
 
-    core.log.info("timer created to report server info, interval: ",
-                  report_interval)
+    core.log.info("timer update the server info ttl, current ttl: ", report_ttl)
 end
 
 
diff --git a/conf/config-default.yaml b/conf/config-default.yaml
index ed10137..cbe655e 100644
--- a/conf/config-default.yaml
+++ b/conf/config-default.yaml
@@ -372,8 +372,7 @@ plugin_attr:
       ip: 127.0.0.1
       port: 9091
   server-info:
-    report_interval: 60  # server info report interval (unit: second)
-    report_ttl: 3600     # live time for server info in etcd (unit: second)
+    report_ttl: 60     # live time for server info in etcd (unit: second)
   dubbo-proxy:
     upstream_multiplex_count: 32
   request-id:
diff --git a/docs/en/latest/plugins/server-info.md b/docs/en/latest/plugins/server-info.md
index 6aacab2..9ca682d 100644
--- a/docs/en/latest/plugins/server-info.md
+++ b/docs/en/latest/plugins/server-info.md
@@ -38,9 +38,7 @@ The meaning of each item in server information is following:
 
 | Name    | Type | Description |
 |---------|------|-------------|
-| up_time | integer | Elapsed time (in seconds) since APISIX instance was launched, value will be reset when you hot updating APISIX but is kept for intact if you just reloading APISIX. |
 | boot_time | integer | Bootstrap time (UNIX timestamp) of the APISIX instance, value will be reset when you hot updating APISIX but is kept for intact if you just reloading APISIX. |
-| last_report_time | integer | Last reporting time (UNIX timestamp). |
 | id | string | APISIX instance id. |
 | etcd_version | string | The etcd cluster version that APISIX is using, value will be `"unknown"` if the network (to etcd) is partitioned. |
 | version | string | APISIX version. |
@@ -75,16 +73,14 @@ We can change the report configurations in the `plugin_attr` section of `conf/co
 
 | Name         | Type   | Default  | Description                                                          |
 | ------------ | ------ | -------- | -------------------------------------------------------------------- |
-| report_interval | integer | 60 | the interval to report server info to etcd (unit: second, maximum: 3600, minimum: 60). |
-| report_ttl | integer | 7200 | the live time for server info in etcd (unit: second, maximum: 86400, minimum: 3600). |
+| report_ttl | integer | 36 | the live time for server info in etcd (unit: second, maximum: 86400, minimum: 3). |
 
-Here is an example, which modifies the `report_interval` to 10 minutes and sets the `report_ttl` to one hour.
+Here is an example, which modifies the `report_ttl` to one minute.
 
 ```yaml
 plugin_attr:
   server-info:
-    report_interval: 600,
-    report_ttl: 3600
+    report_ttl: 60
 ```
 
 ## Test Plugin
@@ -95,8 +91,6 @@ After enabling this plugin, you can access these data through the plugin Control
 $ curl http://127.0.0.1:9090/v1/server_info -s | jq .
 {
   "etcd_version": "3.5.0",
-  "up_time": 9460,
-  "last_report_time": 1608531519,
   "id": "b7ce1c5c-b1aa-4df7-888a-cbe403f3e948",
   "hostname": "fedora32",
   "version": "2.1",
diff --git a/docs/zh/latest/plugins/server-info.md b/docs/zh/latest/plugins/server-info.md
index 3abe779..8db06b0 100644
--- a/docs/zh/latest/plugins/server-info.md
+++ b/docs/zh/latest/plugins/server-info.md
@@ -39,14 +39,12 @@ title: server-info
 服务信息中每一项的含义如下:
 
 | 名称             | 类型    | 描述                                                                                                                    |
-| ---------------- | ------- | ----------------------------------------------------------------------------------------------------------------------- |
-| up_time          | integer | APISIX 服务实例当前的运行时间(单位:秒), 如果对 APISIX 进行热更新操作,该值将被重置;普通的 reload 操作不会影响该值。 |
-| boot_time        | integer | APISIX 服务实例的启动时间(UNIX 时间戳),如果对 APIISIX 进行热更新操作,该值将被重置;普通的 reload 操作不会影响该值。 |
-| last_report_time | integer | 最近一次服务信息上报的时间 (UNIX 时间戳)。                                                                            |
+| ---------------- | ------- | --------------------------------------------------------------------------------------------------------------------- |
+| boot_time        | integer | APISIX 服务实例的启动时间(UNIX 时间戳),如果对 APIISIX 进行热更新操作,该值将被重置;普通的 reload 操作不会影响该值。               |
 | id               | string  | APISIX 服务实例 id 。                                                                                                   |
-| etcd_version     | string  | etcd 集群的版本信息,如果 APISIX 和 etcd 集群之间存在网络分区,该值将设置为 `"unknown"`。                               |
+| etcd_version     | string  | etcd 集群的版本信息,如果 APISIX 和 etcd 集群之间存在网络分区,该值将设置为 `"unknown"`。                                       |
 | version          | string  | APISIX 版本信息。                                                                                                       |
-| hostname         | string  | APISIX 所部署的机器或 pod 的主机名信息。                                                                                |
+| hostname         | string  | APISIX 所部署的机器或 pod 的主机名信息。                                                                                   |
 
 ## 插件属性
 
@@ -76,18 +74,15 @@ plugins:                          # plugin list
 我们可以在 `conf/config.yaml` 文件的 `plugin_attr` 一节中修改上报配置。
 
 | 名称            | 类型    | 默认值 | 描述                                                               |
-| --------------- | ------- | ------ | ------------------------------------------------------------------ |
-| report_interval | integer | 60     | 上报服务信息至 etcd 的间隔(单位:秒,最大值:3600,最小值:60)   |
-| report_ttl      | integer | 7200   | etcd 中服务信息保存的 TTL(单位:秒,最大值:86400,最小值:3600) |
+| --------------- | ------- | ------ | --------------------------------------------------------------- |
+| report_ttl      | integer | 36   | etcd 中服务信息保存的 TTL(单位:秒,最大值:86400,最小值:3)            |
 
-下面的例子将 `report_interval` 修改成了 10 分钟,并将 `report_ttl` 修改成了 1
-小时:
+下面的例子将 `report_ttl` 修改成了 1 分钟:
 
 ```yaml
 plugin_attr:
   server-info:
-    report_interval: 600
-    report_ttl: 3600
+    report_ttl: 60
 ```
 
 ## 测试插件
@@ -98,8 +93,6 @@ plugin_attr:
 $ curl http://127.0.0.1:9090/v1/server_info -s | jq .
 {
   "etcd_version": "3.5.0",
-  "up_time": 9460,
-  "last_report_time": 1608531519,
   "id": "b7ce1c5c-b1aa-4df7-888a-cbe403f3e948",
   "hostname": "fedora32",
   "version": "2.1",
diff --git a/t/plugin/server-info.t b/t/plugin/server-info.t
index 2e382a5..6963fd2 100644
--- a/t/plugin/server-info.t
+++ b/t/plugin/server-info.t
@@ -34,6 +34,20 @@ no_long_string();
 no_root_location();
 no_shuffle();
 
+add_block_preprocessor(sub {
+    my ($block) = @_;
+
+    if (!defined $block->request) {
+        $block->set_value("request", "GET /t");
+    }
+
+    if (!defined $block->error_log && !defined $block->no_error_log) {
+        $block->set_value("no_error_log", "[error]");
+    }
+
+    $block;
+});
+
 run_tests;
 
 __DATA__
@@ -46,7 +60,7 @@ plugins:
     - server-info
 plugin_attr:
     server-info:
-        report_interval: 60
+        report_ttl: 60
 --- config
 location /t {
     content_by_lua_block {
@@ -65,58 +79,12 @@ location /t {
         ngx.say(json.encode(value))
     }
 }
---- request
-GET /t
 --- response_body eval
-qr/^{"boot_time":\d+,"etcd_version":"[\d\.]+","hostname":"[a-zA-Z\-0-9\.]+","id":[a-zA-Z\-0-9]+,"last_report_time":\d+,"up_time":\d+,"version":"[\d\.]+"}$/
---- no_error_log
-[error]
---- error_log
-timer created to report server info, interval: 60
-
-
-
-=== TEST 2: verify the data integrity after reloading
---- yaml_config
-apisix:
-    id: 123456
-plugins:
-    - server-info
-plugin_attr:
-    server-info:
-        report_interval: 60
---- config
-location /t {
-    content_by_lua_block {
-        local core = require("apisix.core")
-        local key = "/data_plane/server_info/" .. core.id.get()
-        local res, err = core.etcd.get(key)
-        if err ~= nil then
-            ngx.status = 500
-            ngx.say(err)
-            return
-        end
-
-        local value = res.body.node.value
-        if value.up_time >= 2 then
-            ngx.say("integral")
-        else
-            ngx.say("reset")
-        end
-    }
-}
---- request
-GET /t
---- response_body
-integral
---- no_error_log
-[error]
---- error_log
-timer created to report server info, interval: 60
+qr/^{"boot_time":\d+,"etcd_version":"[\d\.]+","hostname":"[a-zA-Z\-0-9\.]+","id":[a-zA-Z\-0-9]+,"version":"[\d\.]+"}$/
 
 
 
-=== TEST 3: get server_info from plugin control API
+=== TEST 2: get server_info from plugin control API
 --- yaml_config
 apisix:
     id: 123456
@@ -136,9 +104,5 @@ location /t {
         ngx.say(json.encode(body))
     }
 }
---- request
-GET /t
 --- response_body eval
-qr/^{"boot_time":\d+,"etcd_version":"[\d\.]+","hostname":"[a-zA-Z\-0-9\.]+","id":[a-zA-Z\-0-9]+,"last_report_time":\d+,"up_time":\d+,"version":"[\d\.]+"}$/
---- no_error_log
-[error]
+qr/^{"boot_time":\d+,"etcd_version":"[\d\.]+","hostname":"[a-zA-Z\-0-9\.]+","id":[a-zA-Z\-0-9]+,"version":"[\d\.]+"}$/