动态限流器
在处理完节点/服务的状态时,会并行处理限流器的扩缩容。因为要想做到服务升降级,从而减少进入服务节点的流量,限流器是不可缺少的一部分。而要想要限流器做到随着服务升降级而动态进行限流。就需要用到动态扩缩容的概念
在tl-ops-manage中,我提供了两种限流算法,并整合了这两种算法到熔断逻辑中,我称之为熔断限流器,目前有 令牌桶限流器
,漏桶限流器
。下面我着重说明下两种限流器的扩缩容实现和整合
令牌桶限流器
令牌桶扩容
我们知道令牌桶是一个容器,之所以它能实现限流,是因为他有最大最小边界值,我们假设桶最大容量为capacity
, 那么令牌数量的范围就是 [0, capacity]
,在某一时刻,这里我们假定容量为 [0, capacity/2]
,也就是服务处理请求的能力将下降一半,发生扩容后,能够存放令牌的数量将变为 [0, (capacity/2) * 扩容比例]
下面我们看具体实现代码,可以看到首先从shared中拿出 capacity,判定是否在合法值内,如果是,再拿到扩容比例,将其扩容,
# 代码位置 : limit/fuse/tl_ops_limit_fuse_token_bucket_.lua
-- 扩容 熔断定时器中保证锁,所以这里不加锁
local tl_ops_limit_token_expand = function( service_name, node_id )
local token_mode = tl_ops_limit_token_mode( service_name, node_id)
if not token_mode then
return false
end
local capacity_key = tl_ops_utils_func:gen_node_key(token_mode.cache_key.capacity, service_name, node_id)
local capacity = shared:get(capacity_key)
if not capacity then
local res, _ = shared:set(capacity_key, token_mode.options.capacity)
if not res then
return false
end
capacity = token_mode.options.capacity
end
local expand_key = tl_ops_utils_func:gen_node_key(token_mode.cache_key.expand, service_name, node_id)
local expand = shared:get(expand_key)
if not expand then
local res, _ = shared:set(expand_key, token_mode.options.expand)
if not res then
return false
end
expand = token_mode.options.expand
end
tlog:dbg("token expand=",expand, ",service_name=", service_name, ",node_id=",node_id,",expand_key=", expand_key)
-- 扩容量 = 当前桶容量 * 比例
-- 扩容最大容量暂时不限制大小,理论上扩容前,必定伴随一次缩容,所以不最大容量会超过设置的最大容量
local expand_capacity = capacity * expand
local capacity_key = tl_ops_utils_func:gen_node_key(token_mode.cache_key.capacity, service_name, node_id)
local res ,_ = shared:incr(capacity_key, expand_capacity)
if not res or res == false then
return false
end
return true
end
令牌桶缩容
明白了,上面的的扩容,自然也就能明白缩容了,只是将扩容的值补充负号即可。部分代码如下
# 代码位置 : limit/fuse/tl_ops_limit_fuse_token_bucket_.lua
-- 缩容量 = -当前桶容量 * 比例
local shrink_capacity = capacity * shrink
local res ,_ = shared:incr(capacity_key, -shrink_capacity)
if not res or res == false then
return false
end
漏桶限流器
漏桶扩容
漏桶的扩缩容也是类似于令牌桶,部分代码如下
# 代码位置 : limit/fuse/tl_ops_limit_fuse_leak_bucket_.lua
-- 扩容量 = 当前桶容量 * 比例
local expand_capacity = capacity * expand
local res ,_ = shared:incr(capacity_key, expand_capacity)
if not res or res == false then
return false
end
漏桶缩容
# 代码位置 : limit/fuse/tl_ops_limit_fuse_leak_bucket_.lua
-- 缩容量 = -当前桶容量 * 比例
local shrink_capacity = capacity * shrink
local res ,_ = shared:incr(capacity_key, -shrink_capacity)
if not res or res == false then
return false
end