ATS插件中配置文件自动更新思路

在ATS插件开发过程中,我们经常会需要如下业务需求:
某个插件的配置文件更新了,我们需要让新的配置文件生效,但是我们不想重启ATS.因为作为CDN行业的缓存服务器来说,很大部分缓存是直接使用内存存放的,重启ATS意味着你以前所有的缓存都将清空,这是一个巨大的代价,万不得已我们不会这么办.
那么如何在不重启ATS的情况下,也能让插件的配置文件自动更新呢?
经过研究代码,我发现事实上ATS是专门提供了这个功能的,也就是通过traffic_manager进程来触发traffic_server进程来重新加载新的配置文件,得到配置的平滑过渡,类似Nginx的reload配置文件功能吧.

先不妨区分几个概念:
自动更新, 即时更新, 手动更新
自动更新,一般是程序会在指定间隔时间内检测一下配置文件,判断配置文件的last_modified时间是否有变动, 有变动就认为是配置文件更新了,哪怕你仅对配置文件做一下touch命令而完全没有更改它的内容也是这样,这种定期检测的方法会有开销;
即时更新,一般指当配置文件有更新时,让程序重新加载新配置文件,可以手动触发也可以让程序自动加载;
手动更新,一般就是指重启ATS程序,重新加载所有的配置文件,不管大部分是否有变动,这种方法一般不可取.
我们这里的功能就是插件配置文件的即时更新,就是通过外部的一个信号来触发ATS让它达到重新加载配置文件的目的.是一种最优的解决方案.因为我们在更新配置文件的同时,就通过外部信号让它更新配置文件了,不需要程序自身的探测,也不需要进程重启.

下面说明插件配置文件即时更新的方法,整个过程分为如下几个阶段.
一.注册
以ATS源码中的trafficserver-4.1.2/plugins/gzip/gzip.cc插件为例,先生成一个Continuation,我称为状态机
TSCont contp = TSConCreate(cb_func, NULL);
设置私有数据
TSContDataSet(contp, p=配置文件名称)
注册到Traffic_manager进程
TSMgmtUpdateRegister(contp, plugin_name)
编写配置文件载入函数,它被contp的回调函数cb_func()函数调用
read_configuration(contp)
插入全局hash表,它是动态创建的,按照这种方式更新配置文件的插件的TSCont都会放入这个全局hash table中
InkAPI.cc::api_init()
ConfigUpdateCbTable = new ConfigUpdateCbTable
global_config_cbs->insert()

二.触发
下面使用traffic_line触发,分析traffic_line -x的执行流程如下
main()=>process_args()=>TSinit()=>handleArgInvocation()=>TSTerminate()=>Terminate()
                                     || -x
                                     TSReconfigure()=>Reconfigure()=>ConfigFiles->rereadConfig()=> (如果检测到有配置文件更新,这里会打印出来)
                                     lmgmt->signalEvent(MGMT_EVENT_PLUGIN_CONFIG_UPDATE, "*")
                                     || enqueue
                                     mgmt_event_queue()
                                     ||
                                     LocalManager::processEventQueue()
                                     ||
                                     lmgmt=>sendMgmMsgToProcesses()
                                     ||
                                     mgmt_write_pipe()
                                     || unix socket类型的IPC进程间通信
                                     pmgmt->handleMgmtMsgFromLM()
                                     || MGMT_EVENT_PLUGIN_CONFIG_UPDATE
                                     configUpdateCbTable::invoke(plugin_name)
                                     ||
                                     configUpdateCbTable::invoke(contp)
                                     ||
                                     .......

三.执行
继续接上面的流程
ConfigUpdateCbTable::invoke(contp) 
||
eventProcessor.schedule_imm(new ConfigUpdateCallback(tonp), ET_TASK) 由TS进程中的ET_TASK类型的线程立即执行配置更新
||
用户自己定义的continuation
||
执行用户自己的状态机回调event_handler(),在这里就是插件中定义的加载配置文件的函数read_configuration:

四.使用方法
参见上面一部分的分析,注意触发这个事件的方法是在命令行执行
traffic_line -x

五.缺点
如果有多个插件都采用这种方法,则多个插件都会重新加载其配置文件

备注:要完全理解这种方法的整个流程,需要你跟着上面的线索阅读相关的调用代码,还需要使用gdb调试traffic_manager和traffic_server进程之间的IPC通信,你可以打开records.config的调试开关,指定你要打印的模块消息的前缀如下:
diags.debug.enabled INT 0 改为1 开启调试开关
diags.debug.tags STRING lm.*|pmgmt.* 只打印指定的信息

然后就能看到下面的消息交互了


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值