in kong/kong/init.lua [974:1139]
function Kong.balancer()
local now_ms = now() * 1000
local ctx = ngx.ctx
if not ctx.KONG_BALANCER_START then
ctx.KONG_BALANCER_START = now_ms
if is_stream_module then
if ctx.KONG_PREREAD_START and not ctx.KONG_PREREAD_ENDED_AT then
ctx.KONG_PREREAD_ENDED_AT = ctx.KONG_BALANCER_START
ctx.KONG_PREREAD_TIME = ctx.KONG_PREREAD_ENDED_AT -
ctx.KONG_PREREAD_START
end
else
if ctx.KONG_REWRITE_START and not ctx.KONG_REWRITE_ENDED_AT then
ctx.KONG_REWRITE_ENDED_AT = ctx.KONG_ACCESS_START or
ctx.KONG_BALANCER_START
ctx.KONG_REWRITE_TIME = ctx.KONG_REWRITE_ENDED_AT -
ctx.KONG_REWRITE_START
end
if ctx.KONG_ACCESS_START and not ctx.KONG_ACCESS_ENDED_AT then
ctx.KONG_ACCESS_ENDED_AT = ctx.KONG_BALANCER_START
ctx.KONG_ACCESS_TIME = ctx.KONG_ACCESS_ENDED_AT -
ctx.KONG_ACCESS_START
end
end
end
ctx.KONG_PHASE = PHASES.balancer
local balancer_data = ctx.balancer_data
local tries = balancer_data.tries
local current_try = {}
balancer_data.try_count = balancer_data.try_count + 1
tries[balancer_data.try_count] = current_try
current_try.balancer_start = now_ms
if balancer_data.try_count > 1 then
local previous_try = tries[balancer_data.try_count - 1]
previous_try.state, previous_try.code = get_last_failure()
local balancer_instance = balancer_data.balancer
if balancer_instance then
if previous_try.state == "failed" then
if previous_try.code == 504 then
balancer_instance.report_timeout(balancer_data.balancer_handle)
else
balancer_instance.report_tcp_failure(balancer_data.balancer_handle)
end
else
balancer_instance.report_http_status(balancer_data.balancer_handle,
previous_try.code)
end
end
local ok, err, errcode = balancer.execute(balancer_data, ctx)
if not ok then
ngx_log(ngx_ERR, "failed to retry the dns/balancer resolver for ",
tostring(balancer_data.host), "' with: ", tostring(err))
ctx.KONG_BALANCER_ENDED_AT = get_updated_now_ms()
ctx.KONG_BALANCER_TIME = ctx.KONG_BALANCER_ENDED_AT - ctx.KONG_BALANCER_START
ctx.KONG_PROXY_LATENCY = ctx.KONG_BALANCER_ENDED_AT - ctx.KONG_PROCESSING_START
return ngx.exit(errcode)
end
if is_http_module then
ok, err = balancer.set_host_header(balancer_data, var.upstream_scheme, var.upstream_host, true)
if not ok then
ngx_log(ngx_ERR, "failed to set balancer Host header: ", err)
return ngx.exit(500)
end
end
else
local retries = balancer_data.retries
if retries > 0 then
set_more_tries(retries)
end
end
local pool_opts
local kong_conf = kong.configuration
if kong_conf.upstream_keepalive_pool_size > 0 and is_http_module then
local pool = balancer_data.ip .. "|" .. balancer_data.port
if balancer_data.scheme == "https" then
pool = pool .. "|" .. var.upstream_host
if ctx.service and ctx.service.client_certificate then
pool = pool .. "|" .. ctx.service.client_certificate.id
end
end
pool_opts = {
pool = pool,
pool_size = kong_conf.upstream_keepalive_pool_size,
}
end
current_try.ip = balancer_data.ip
current_try.port = balancer_data.port
ngx_log(ngx_DEBUG, "setting address (try ", balancer_data.try_count, "): ",
balancer_data.ip, ":", balancer_data.port)
local ok, err = set_current_peer(balancer_data.ip, balancer_data.port, pool_opts)
if not ok then
ngx_log(ngx_ERR, "failed to set the current peer (address: ",
tostring(balancer_data.ip), " port: ", tostring(balancer_data.port),
"): ", tostring(err))
ctx.KONG_BALANCER_ENDED_AT = get_updated_now_ms()
ctx.KONG_BALANCER_TIME = ctx.KONG_BALANCER_ENDED_AT - ctx.KONG_BALANCER_START
ctx.KONG_PROXY_LATENCY = ctx.KONG_BALANCER_ENDED_AT - ctx.KONG_PROCESSING_START
return ngx.exit(500)
end
ok, err = set_timeouts(balancer_data.connect_timeout / 1000,
balancer_data.send_timeout / 1000,
balancer_data.read_timeout / 1000)
if not ok then
ngx_log(ngx_ERR, "could not set upstream timeouts: ", err)
end
if pool_opts then
ok, err = enable_keepalive(kong_conf.upstream_keepalive_idle_timeout,
kong_conf.upstream_keepalive_max_requests)
if not ok then
ngx_log(ngx_ERR, "could not enable connection keepalive: ", err)
end
ngx_log(ngx_DEBUG, "enabled connection keepalive (pool=", pool_opts.pool,
", pool_size=", pool_opts.pool_size,
", idle_timeout=", kong_conf.upstream_keepalive_idle_timeout,
", max_requests=", kong_conf.upstream_keepalive_max_requests, ")")
end
ctx.KONG_BALANCER_ENDED_AT = get_updated_now_ms()
ctx.KONG_BALANCER_TIME = ctx.KONG_BALANCER_ENDED_AT - ctx.KONG_BALANCER_START
local try_latency = ctx.KONG_BALANCER_ENDED_AT - current_try.balancer_start
current_try.balancer_latency = try_latency
ctx.KONG_PROXY_LATENCY = ctx.KONG_BALANCER_ENDED_AT - ctx.KONG_PROCESSING_START
end