aboutsummaryrefslogtreecommitdiffstats
path: root/openresty-ext/src/assembly/resources/openresty/nginx/luaext/loadbalance/baseupstream.lua
blob: 9361eeac167a7525098d9b288b83264544829693 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
--[[

    Copyright (C) 2017-2018 ZTE, Inc. and others. All rights reserved. (ZTE)

    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.

--]]

local _M = {
	_VERSION = '1.0.0'
}

local roundrobin = require "loadbalance.policy.roundrobin"
local consistent_hash = require "loadbalance.policy.consistent_hash"
local tbl_util  = require('lib.utils.table_util')
local svc_util  =  require('lib.utils.svc_util')
local peerwatcher = require "core.peerwatcher"
local tbl_isempty = tbl_util.isempty
local svc_use_own_upstream = svc_util.use_own_upstream

function _M.get_backserver(svc_key,servers)
	if tbl_isempty(servers) then return nil,"server list is empty" end

	local servers_num = #servers
	if not ngx.ctx.tried_num then
		ngx.ctx.tried_num = 0
	end
	local server
	if servers_num==1 then
		ngx.ctx.tried_num = ngx.ctx.tried_num+1
		-- return it directly if there is only one server
		server = servers[1]
		if peerwatcher.is_server_ok(svc_key,server) then
			return server,"" 
		else 
			return nil,"only one server but is not available"
		end
	end

	-- A temporary solution, plase modify it when add lb_policy to svc_info
    local svc_info = ngx.ctx.svc_info
    if svc_use_own_upstream(svc_info) then
		svc_info.lb_policy = "ip_hash"
	else
		svc_info.lb_policy = "roundrobin"
	end


	local mode = svc_info.lb_policy
	if mode ~= nil then
	    if mode == "ip_hash" then
		    -- iphash
		    for i=ngx.ctx.tried_num+1,servers_num do
		        ngx.ctx.tried_num = ngx.ctx.tried_num+1
		        server = consistent_hash.select_backserver(servers,svc_key)
		        if peerwatcher.is_server_ok(svc_key,server) then
		            return server,""
		        end
            end
            return nil,"serveral server but no one is available"

        elseif mode == "roundrobin" then
             -- roundrobin
		    for i=ngx.ctx.tried_num+1,servers_num do
			    ngx.ctx.tried_num = ngx.ctx.tried_num+1
			    server = roundrobin.select_backserver(servers,svc_key)
			    if peerwatcher.is_server_ok(svc_key,server) then
			        return server,""
			    end
            end
            return nil,"serveral server but no one is available"
        end

    end

end

function _M.can_retry(svc_key,servers)
	return ngx.ctx.tried_num < #servers
end

function _M.mark_srv_failed(svc_key, srv)
	peerwatcher.set_srv_status(svc_key, srv, true)
end

function _M.check_and_reset_srv_status_ifneed(svc_key, servers)
	peerwatcher.check_and_reset_srv_status_ifneed(svc_key,servers)
end
return _M