Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

luarocks: added new dependency lua-resty-healthcheck. #249

Merged
merged 15 commits into from
Jul 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions COPYRIGHT
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,39 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

%%%%%%%%%

lua-resty-healthcheck

https://github.com/Kong/lua-resty-healthcheck

Apache License 2

Copyright 2017-2018 Kong Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

%%%%%%%%%

lua-resty-worker-events

https://github.com/Kong/lua-resty-worker-events

Apache License 2

This module is licensed under the Apache 2.0 license.

Copyright (C) 2016, by Thijs Schreijer, Kong Inc.

All rights reserved.

%%%%%%%%%
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ help:
### dev: Create a development ENV
.PHONY: dev
dev:
./utils/update_nginx_conf_dev.sh
ifeq ($(UNAME),Darwin)
luarocks install --lua-dir=$(LUA_JIT_DIR) rockspec/apisix-dev-0.rockspec --tree=deps --only-deps --local
else ifneq ($(LUAROCKS_VER),'luarocks 3.')
Expand Down
1 change: 1 addition & 0 deletions bin/apisix
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ http {
lua_shared_dict plugin-limit-count 10m;
lua_shared_dict prometheus-metrics 10m;
lua_shared_dict plugin-limit-conn 10m;
lua_shared_dict worker-events 10m;

lua_ssl_verify_depth 5;
ssl_session_timeout 86400;
Expand Down
14 changes: 9 additions & 5 deletions conf/nginx.conf
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
master_process on;

worker_processes 1;
worker_cpu_affinity auto;

error_log logs/error.log warn;
pid logs/nginx.pid;
Expand All @@ -22,10 +21,12 @@ http {
lua_package_path "$prefix/deps/share/lua/5.1/?.lua;$prefix/lua/?.lua;/usr/share/lua/5.1/?.lua;;";
lua_package_cpath "$prefix/deps/lib64/lua/5.1/?.so;$prefix/deps/lib/lua/5.1/?.so;/usr/lib64/lua/5.1/?.so;;";

lua_shared_dict plugin-limit-req 10m;
lua_shared_dict plugin-limit-count 10m;
lua_shared_dict prometheus-metrics 10m;
lua_shared_dict plugin-limit-conn 10m;
lua_shared_dict plugin-limit-req 10m;
lua_shared_dict plugin-limit-count 10m;
lua_shared_dict prometheus-metrics 10m;
lua_shared_dict plugin-limit-conn 10m;
lua_shared_dict upstream-healthcheck 32m;
lua_shared_dict worker-events 10m;

lua_ssl_verify_depth 5;
ssl_session_timeout 86400;
Expand All @@ -37,6 +38,9 @@ http {

lua_http10_buffering off;

lua_regex_match_limit 100000;
lua_regex_cache_max_entries 8192;

log_format main '$remote_addr - $remote_user [$time_local] $http_host "$request" $status $body_bytes_sent $request_time "$http_referer" "$http_user_agent" $upstream_addr $upstream_status $upstream_response_time';

access_log logs/access.log main buffer=32768 flush=3;
Expand Down
11 changes: 10 additions & 1 deletion lua/apisix.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ local require = require
local core = require("apisix.core")
local router = require("apisix.http.route").get
local plugin = require("apisix.plugin")
local load_balancer = require("apisix.http.balancer").run
local service_fetch = require("apisix.http.service").get
local ssl_match = require("apisix.http.ssl").match
local admin_init = require("apisix.admin.init")
Expand All @@ -15,6 +14,8 @@ local ngx_exit = ngx.exit
local ngx_ERROR = ngx.ERROR
local math = math
local match_opts = {}
local error = error
local load_balancer


local _M = {version = 0.1}
Expand Down Expand Up @@ -44,6 +45,14 @@ end


function _M.http_init_worker()
local we = require("resty.worker.events")
local ok, err = we.configure({shm = "worker-events", interval = 0.1})
membphis marked this conversation as resolved.
Show resolved Hide resolved
if not ok then
error("failed to init worker event: " .. err)
end

load_balancer = require("apisix.http.balancer").run

require("apisix.admin.init").init_worker()

require("apisix.http.route").init_worker()
Expand Down
92 changes: 32 additions & 60 deletions lua/apisix/core/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,66 +45,37 @@ local id_schema = {
}
}

-- todo: chash and roundrobin have different properties, we may support
-- this limitation later.

-- {
-- "definitions": {
-- "nodes": {
-- "patternProperties": {
-- ".*": {
-- "minimum": 1,
-- "type": "integer"
-- }
-- },
-- "minProperties": 1,
-- "type": "object"
-- }
-- },
-- "type": "object",
-- "anyOf": [
-- {
-- "properties": {
-- "type": {
-- "type": "string",
-- "enum": [
-- "roundrobin"
-- ]
-- },
-- "nodes": {
-- "$ref": "#/definitions/nodes"
-- }
-- },
-- "required": [
-- "type",
-- "nodes"
-- ],
-- "additionalProperties": false
-- },
-- {
-- "properties": {
-- "type": {
-- "type": "string",
-- "enum": [
-- "chash"
-- ]
-- },
-- "nodes": {
-- "$ref": "#/definitions/nodes"
-- },
-- "key": {
-- "type": "string"
-- }
-- },
-- "required": [
-- "key",
-- "type",
-- "nodes"
-- ],
-- "additionalProperties": false
-- }
-- ]
-- }

-- todo: support all option
-- default value: https://github.com/Kong/lua-resty-healthcheck/
-- blob/master/lib/resty/healthcheck.lua#L1121
local health_checker = {
type = "object",
properties = {
active = {
type = "object",
properties = {
http_path = {type = "string"},
membphis marked this conversation as resolved.
Show resolved Hide resolved
host = {type = "string"},
healthy = {
type = "object",
properties = {
interval = {type = "integer", minimum = 1},
successes = {type = "integer", minimum = 1}
}
},
unhealthy = {
type = "object",
properties = {
interval = {type = "integer", minimum = 1},
http_failures = {type = "integer", minimum = 1}
}
membphis marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}
}


local upstream_schema = {
type = "object",
Expand All @@ -126,6 +97,7 @@ local upstream_schema = {
type = "string",
enum = {"chash", "roundrobin"}
},
checks = health_checker,
key = {
description = "the key of chash for dynamic load balancing",
type = "string",
Expand Down
12 changes: 12 additions & 0 deletions lua/apisix/core/table.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
local newproxy = newproxy
local getmetatable = getmetatable
local setmetatable = setmetatable
local select = select

local _M = {
Expand Down Expand Up @@ -31,4 +34,13 @@ function _M.set(tab, ...)
end


-- only work under lua51 or luajit
function _M.setmt__gc(t, mt)
local prox = newproxy(true)
getmetatable(prox).__gc = function() mt.__gc(t) end
t[prox] = true
return setmetatable(t, mt)
end


return _M
94 changes: 76 additions & 18 deletions lua/apisix/http/balancer.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local roundrobin = require("resty.roundrobin")
local healthcheck = require("resty.healthcheck")
local roundrobin = require("resty.roundrobin")
local resty_chash = require("resty.chash")
local balancer = require("ngx.balancer")
local core = require("apisix.core")
Expand All @@ -14,7 +15,7 @@ local tostring = tostring


local module_name = "balancer"
local lrucache_get = core.lrucache.new({ttl = 300, count = 256})
local lrucache_server_picker = core.lrucache.new({ttl = 300, count = 256})


local _M = {
Expand All @@ -23,12 +24,52 @@ local _M = {
}


local function parse_addr(addr)
local pos = find_str(addr, ":", 1, true)
membphis marked this conversation as resolved.
Show resolved Hide resolved
if not pos then
return addr, 80
end

local host = sub_str(addr, 1, pos - 1)
local port = sub_str(addr, pos + 1)
return host, tonumber(port)
end


local function fetch_health_nodes(upstream)
if not upstream.checks then
return upstream.nodes
end

local host = upstream.checks and upstream.checks.host
local checker = upstream.checker
local up_nodes = core.table.new(0, #upstream.nodes)

for addr, weight in pairs(upstream.nodes) do
local ip, port = parse_addr(addr)
local ok = checker:get_target_status(ip, port, host)
if ok then
up_nodes[addr] = weight
end
end

if core.table.nkeys(up_nodes) == 0 then
core.log.warn("all upstream nodes is unhealth, use default")
up_nodes = upstream.nodes
end
return up_nodes
end


local function create_server_picker(upstream)
core.log.info("create create_obj, type: ", upstream.type,
" nodes: ", core.json.delay_encode(upstream.nodes))

if upstream.type == "roundrobin" then
local picker = roundrobin:new(upstream.nodes)
local up_nodes = fetch_health_nodes(upstream)
core.log.info("upstream nodes: ", core.json.delay_encode(up_nodes))

local picker = roundrobin:new(up_nodes)
return {
get = function ()
return picker:find()
Expand All @@ -37,10 +78,11 @@ local function create_server_picker(upstream)
end

if upstream.type == "chash" then
local up_nodes = fetch_health_nodes(upstream)
local str_null = str_char(0)

local servers, nodes = {}, {}
for serv, weight in pairs(upstream.nodes) do
for serv, weight in pairs(up_nodes) do
local id = str_gsub(serv, ":", str_null)

servers[id] = serv
Expand All @@ -62,18 +104,6 @@ local function create_server_picker(upstream)
end


local function parse_addr(addr)
local pos = find_str(addr, ":", 1, true)
if not pos then
return addr, 80
end

local host = sub_str(addr, 1, pos - 1)
local port = sub_str(addr, pos + 1)
return host, tonumber(port)
end


local function pick_server(route, ctx)
core.log.info("route: ", core.json.delay_encode(route, true))
core.log.info("ctx: ", core.json.delay_encode(ctx, true))
Expand Down Expand Up @@ -107,8 +137,36 @@ local function pick_server(route, ctx)
key = upstream.type .. "#route_" .. route.value.id
end

local server_picker = lrucache_get(key, version,
create_server_picker, upstream)
if upstream.checks and not upstream.checker then
local checker = healthcheck.new({
name = "upstream",
shm_name = "upstream-healthcheck",
checks = upstream.checks,
})

upstream.checker = checker

-- stop the checker by `gc`
core.table.setmt__gc(upstream, {__gc=function() checker:stop() end})

for addr, weight in pairs(upstream.nodes) do
local ip, port = parse_addr(addr)
local ok, err = checker:add_target(ip, port, upstream.checks.host)
if not ok then
core.log.error("failed to add new health check target: ", addr,
" err: ", err)
end
end

core.log.warn("create checks obj for upstream, check")
end

if upstream.checks then
version = version .. "#" .. upstream.checker.status_ver
end

local server_picker = lrucache_server_picker(key, version,
create_server_picker, upstream)
if not server_picker then
return nil, nil, "failed to fetch server picker"
end
Expand Down
1 change: 1 addition & 0 deletions rockspec/apisix-dev-0.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dependencies = {
"lua-resty-ngxvar = 0.3",
"lua-resty-jit-uuid = 0.0.7",
"rapidjson = 0.6.0-1",
"lua-resty-healthcheck-iresty = 1.0.0",
membphis marked this conversation as resolved.
Show resolved Hide resolved
}

build = {
Expand Down
Loading