静态数据同步/预热器
对于静态数据同步的实现,我将静态数据同步做成配置形式,通过配置不同模块名称,来达到自定义同步部分模块的静态数据的目的
执行时机
静态数据同步器在整个nginx生命周期中,只会执行一次,也就是在 init_worker
阶段执行,在此阶段会读取配置的模块的中的静态数据文件,也就是 tl_ops_constant_xxx.lua
文件中的静态配置字段,将静态配置字段与各模块的store文件的最新配置的id进行对比,对增量静态配置进行补充到store文件中
注意 : 由于是需要依赖各模块的静态配置的id来做判断依据,所以静态配置的id对于同步插件来说必不可少且必须唯一。
实现代码
# 代码位置 : plugins/tl_ops_sync/sync_data.lua
-- api策略静态配置数据
local sync_data_balance_api = function ()
local cache_key_list = constant_balance_api.cache_key.list
local data_str, _ = cache_balance_api:get(cache_key_list);
if not data_str then
local res, _ = cache_balance_api:set(cache_key_list, cjson.encode(constant_balance.api.list))
if not res then
tlog:err("sync_data_balance_api new store data err, res=",res)
return tl_ops_rt.error
end
tlog:dbg("sync_data_balance_api new store data, res=",res)
return tl_ops_rt.ok
end
local data = cjson.decode(data_str);
if not data and type(data) ~= 'table' then
tlog:err("sync_data_balance_api err, old=",data)
return tl_ops_rt.error
end
-- 静态配置
local constant_data = constant_balance.api.list
-- 获取需要同步的配置
local add_point = sync_data_need_sync(constant_data.point, data.point)
for i = 1, #add_point do
table.insert(data.point, add_point[i])
end
-- 获取需要同步的配置
local add_random = sync_data_need_sync(constant_data.random, data.random)
for i = 1, #add_random do
table.insert(data.random, add_random[i])
end
local res = cache_balance_api:set(cache_key_list, cjson.encode(data))
if not res then
tlog:err("sync_data_balance_api err, res=",res,",new=",data)
return tl_ops_rt.error
end
tlog:dbg("sync_data_balance_api done, new=",data)
return tl_ops_rt.ok
end
-- 同步静态数据主逻辑
function _M:sync_data_module( module )
if module == 'balance_api' then
return sync_data_balance_api()
elseif module == 'balance_cookie' then
return sync_data_balance_cookie()
elseif module == 'balance_header' then
return sync_data_balance_header()
elseif module == 'balance_param' then
return sync_data_balance_param()
elseif module == 'waf_api' then
return sync_data_waf_api()
elseif module == 'waf_ip' then
return sync_data_waf_ip()
elseif module == 'waf_header' then
return sync_data_waf_header()
elseif module == 'waf_cookie' then
return sync_data_waf_cookie()
elseif module == 'waf_param' then
return sync_data_waf_param()
elseif module == 'waf_cc' then
return sync_data_waf_cc()
else
-- plugin
return sync_data_plugin(module)
end
end
支持插件
考虑到插件也会存在静态数据的变化,同步器插件提供了外部接口来支持其他插件的静态数据同步, sync_data
,同步器插件不负责插件的静态数据同步,只负责外部接口的调用,所以各个插件的静态数据同步需要自行实现 sync_data
逻辑代码。
# 代码位置 : plugins/tl_ops_sync/sync_data.lua
-- 获取某个插件
local sync_data_get_plugin = function(name)
for i = 1, #tlops.plugins do
local plugin = tlops.plugins[i]
if plugin.name == name then
return plugin
end
end
return nil
end
-- 插件静态配置数据
local sync_data_plugin = function (module)
local plugin = sync_data_get_plugin(module)
if not plugin then
tlog:err("sync_data_plugin not plugin, module=",module)
return tl_ops_rt.error
end
if type(plugin.func.sync_data) == 'function' then
local ok, _ = plugin.func:sync_data()
if not ok then
tlog:err("sync_data_plugin sync_data err, module=",module,",err=",_)
return tl_ops_rt.error
end
end
tlog:dbg("sync_data_plugin done, module=",module)
return tl_ops_rt.ok
end