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\.]+"}$/