Skip to content

Commit

Permalink
fix: removed plugin API and use background timer
Browse files Browse the repository at this point in the history
  • Loading branch information
tokers committed Dec 3, 2020
1 parent 2ec4569 commit 2a04e5e
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 160 deletions.
102 changes: 31 additions & 71 deletions apisix/plugins/server-info.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@
--
local require = require
local core = require("apisix.core")
local timers = require("apisix.timers")

local ngx_time = ngx.time
local ngx_timer_at = ngx.timer.at
local ngx_worker_id = ngx.worker.id
local type = type
local ceil = math.ceil

local plugin_name = "server-info"
local boot_time = os.time()
local current_timer
local plugin_name = "server-info"
local schema = {
type = "object",
additionalProperties = false,
Expand All @@ -38,6 +38,13 @@ local attr_schema = {
default = 60,
minimum = 60,
maximum = 3600,
},
report_ttl = {
type = "integer",
description = "live time for server info in etcd",
default = 7200,
minimum = 3600,
maximum = 86400,
}
}
}
Expand Down Expand Up @@ -116,18 +123,11 @@ local function get()
end


local function get_server_info()
local server_info, err = get()
if not server_info then
core.log.error("failed to get server_info: ", err)
return 500, err
local function report(premature, report_ttl)
if premature then
return
end

return 200, core.json.encode(server_info)
end


local function report()
local server_info, err = get()
if not server_info then
core.log.error("failed to get server_info: ", err)
Expand Down Expand Up @@ -158,7 +158,7 @@ local function report()
end

local key = "/data_plane/server_info/" .. server_info.id
local ok, err = core.etcd.set(key, data, 180)
local ok, err = core.etcd.set(key, data, report_ttl)
if not ok then
core.log.error("failed to report server info to etcd: ", err)
return
Expand All @@ -183,11 +183,6 @@ end


function _M.init()
if ngx_worker_id() ~= 0 then
-- only let the No.0 worker to launch timer for server info reporting.
return
end

local ok, err = encode_and_save(uninitialized_server_info(), true)
if not ok then
core.log.error("failed to encode and save server info: ", err)
Expand All @@ -207,68 +202,33 @@ function _M.init()
return
end

local report_interval = attr.report_interval

-- we don't use core.timer and the apisix.timers here for:
-- 1. core.timer is not cancalable, timers will be leaked if plugin
-- reloading happens.
-- 2. the background timer in apisix.timers fires per 500 milliseconds, if
-- report_interval is not multiple of 0.5, the real report interval will be
-- inaccurate over time.
local fn
fn = function(premature, timer)
if premature or timer.cancelled then
return
end

report()
local threshold = ceil(attr.report_interval / timers.check_interval())
local report_ttl = attr.report_ttl
local count = 0

if not timer.cancelled then
local ok, err = ngx_timer_at(report_interval, fn, timer)
if not ok then
core.log.error("failed to create timer to report server info: ", err)
end

else
core.log.warn("server info report timer is cancelled")
local fn = function()
count = count + 1
if count == threshold then
report(nil, report_ttl)
count = 0
end
end

current_timer = {
cancelled = false
}

local ok, err = ngx_timer_at(0, fn, current_timer)
if ok then
core.log.info("timer created to report server info, interval: ",
report_interval)
else
core.log.error("failed to create timer to report server info: ", err)
end
end


function _M.destory()
if ngx_worker_id() ~= 0 then
-- timer exists only in the No.0 worker.
local ok, err = ngx_timer_at(0, report, report_ttl)
if not ok then
core.log.error("failed to create initial timer to report server info: ", err)
return
end

if current_timer then
current_timer.cancelled = true
current_timer = nil
end
timers.register_timer("plugin#server-info", fn, true)

core.log.info("timer created to report server info, interval: ",
attr.report_interval)
end


function _M.api()
return {
{
methods = {"GET"},
uri = "/apisix/server_info",
handler = get_server_info,
},
}
function _M.destory()
timers.unregister_timer("plugin#server-info", true)
end


Expand Down
13 changes: 12 additions & 1 deletion apisix/timers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ local unpack = unpack
local thread_spawn = ngx.thread.spawn
local thread_wait = ngx.thread.wait

local check_interval = 0.5

local timers = {}

Expand Down Expand Up @@ -57,7 +58,12 @@ end


function _M.init_worker()
local timer, err = core.timer.new("background", background_timer, {check_interval = 0.5})
local opts = {
check_interval = check_interval,
sleep_succ = 0,
each_ttl = 0,
}
local timer, err = core.timer.new("background", background_timer, opts)
if not timer then
core.log.error("failed to create background timer: ", err)
return
Expand Down Expand Up @@ -85,4 +91,9 @@ function _M.unregister_timer(name, privileged)
end


function _M.check_interval()
return check_interval
end


return _M
1 change: 1 addition & 0 deletions conf/config-default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,4 @@ plugin_attr:
export_uri: /apisix/prometheus/metrics
server-info:
report_interval: 60 # server info report interval (unit: second)
report_ttl: 3600 # live time for server info in etcd (unit: second)
56 changes: 22 additions & 34 deletions doc/plugins/server-info.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,33 @@

- [**Name**](#name)
- [**Attributes**](#attributes)
- [**API**](#api)
- [API](#api)
- [**How To Enable**](#how-to-enable)
- [**Test Plugin**](#test-plugin)
- [**Disable Plugin**](#disable-plugin)

## Name

`server-info` is a plugin that reports basic server information to etcd periodically and allows us to get them in the data plane through it's API.
`server-info` is a plugin that reports basic server information to etcd periodically.

The meaning of each item in server information is following:

| Name | Type | Description |
|---------|------|-------------|
| up_time | integer | Elapsed time since APISIX instance was launched, 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 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. |
| hostname | string | Hostname of the machine/pod that APISIX is deployed. |

## Attributes

None

## API

This plugin now exposes only one API `/apisix/server_info` to get basic server information.
You may need to use [interceptors](../plugin-interceptors.md) to protect it.

None

## How to Enable

Expand All @@ -57,48 +66,27 @@ plugins: # plugin list
......
```

After starting APISIX and accessing `/apisix/server_info` then you can get server information.
## How to customize the server info report configurations

## How to customize the server info report interval

We can change the report interval in the `plugin_attr` section of `conf/config.yaml`.
We can change the report configurations in the `plugin_attr` section of `conf/config.yaml`.

| Name | Type | Default | Description |
| ------------ | ------ | -------- | -------------------------------------------------------------------- |
| report_interval | number | 60 | the interval (unit: second) to report server info to etcd. |
| 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). |

Here is an example, which modifies the report interval to 10 seconds.
Here is an example, which modifies the `report_interval` to 10 minutes and sets the `report_ttl` to one hour.

```yaml
plugin_attr:
server-info:
report_interval: 10
report_interval: 600,
report_ttl: 3600
```
## Test Plugin
```bash
curl http://127.0.0.1:9080/apisix/server_info -s | jq
{
"up_time": 5,
"last_report_time": 1606551536,
"id": "71cb4999-4349-475d-aa39-c703944a63d3",
"etcd_version": "3.5.0",
"version": "2.0",
"hostname": "gentoo"
}
```

The meaning of each item in server information is following:

| Name | Type | Description |
|---------|------|-------------|
| up_time | integer | Elapsed time since APISIX instance was launched, 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 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. |
| hostname | string | Hostname of the machine/pod that APISIX is deployed. |
The APISIX Dashboard will collects server info in etcd, after enabling this plugin, you may try to check them through Dashboard.
## Disable Plugin
Expand Down
54 changes: 24 additions & 30 deletions doc/zh-cn/plugins/server-info.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,27 @@

## 插件简介

`server-info` 是一款能够定期将服务基本信息上报至 etcd,同时允许我们通过它提供的 API 在数据面访问到这些数据的插件。
`server-info` 是一款能够定期将服务基本信息上报至 etcd 的插件。

服务信息中每一项的含义如下:

| 名称 | 类型 | 描述 |
|---------|------|-------------|
| up_time | integer | APISIX 服务实例当前的运行时间, 如果对 APSIX
进行热更新操作,该值将被重置;普通的 reload 操作不会影响该值。 |
| last_report_time | integer | 最近一次服务信息上报的时间 (UNIX 时间戳)。|
| id | string | APISIX 服务实例 id 。|
| etcd_version | string | etcd 集群的版本信息,如果 APISIX 和 etcd 集群之间存在网络分区,该值将设置为 `"unknown"`|
| version | string | APISIX 版本信息。 |
| hostname | string | APISIX 所部署的机器或 pod 的主机名信息。|

## 插件属性


## 插件接口

此插件提供了接口 `/apisix/server_info`,可以通过 [interceptors](../plugin-interceptors.md) 来保护该接口。

## 启用插件

Expand All @@ -56,50 +68,32 @@ plugins: # plugin list
......
```

在启动 APISIX 之后,即可通过访问 `/apisix/server_info` 来获取服务基本信息。
## 如何自定义服务信息上报配置

## 如何自定义服务信息上报间隔

我们可以在 `conf/config.yaml` 文件的 `plugin_attr` 一节中修改上报间隔。
我们可以在 `conf/config.yaml` 文件的 `plugin_attr` 一节中修改上报配置。

| 名称 | 类型 | 默认值 | 描述 |
| ------------ | ------ | -------- | -------------------------------------------------------------------- |
| report_interval | number | 60 | 上报服务信息至 etcd 的间隔(单位:秒)|
| report_interval | integer | 60 | 上报服务信息至 etcd
的间隔(单位:秒,最大值:3600,最小值:60)|
| report_ttl | integer | 7200 | etcd 中服务信息保存的
TTL(单位:秒,最大值:86400,最小值:3600)|

下面的例子将服务信息上报间隔修改成了 10 秒:
下面的例子将 `report_interval` 修改成了 10 秒,并将 `report_ttl` 修改成了 1
小时:

```yaml
plugin_attr:
server-info:
report_interval: 10
report_ttl: 3600
```
## 测试插件
```bash
curl http://127.0.0.1:9080/apisix/server_info -s | jq
{
"up_time": 5,
"last_report_time": 1606551536,
"id": "71cb4999-4349-475d-aa39-c703944a63d3",
"etcd_version": "3.5.0",
"version": "2.0",
"hostname": "gentoo"
}
```

服务信息中每一项的含义如下:
Apache APISIX Dashboard 会收集上报到 etcd 中的服务信息,在启用这个插件后,你可以通过 APISIX Dashboard 来查看这些数据。
| 名称 | 类型 | 描述 |
|---------|------|-------------|
| up_time | integer | APISIX 服务实例当前的运行时间, 如果对 APSIX
进行热更新操作,该值将被重置;普通的 reload 操作不会影响该值。 |
| last_report_time | integer | 最近一次服务信息上报的时间 (UNIX 时间戳)。|
| id | string | APISIX 服务实例 id 。|
| etcd_version | string | etcd 集群的版本信息,如果 APISIX 和 etcd 集群之间存在网络分区,该值将设置为 `"unknown"`|
| version | string | APISIX 版本信息。 |
| hostname | string | APISIX 所部署的机器或 pod 的主机名信息。|
## 禁用插件
Expand Down
Loading

0 comments on commit 2a04e5e

Please sign in to comment.