ATS插件中配置文件自动更新思路
生活随笔
收集整理的這篇文章主要介紹了
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.* 只打印指定的信息
某個插件的配置文件更新了,我們需要讓新的配置文件生效,但是我們不想重啟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.* 只打印指定的信息
然后就能看到下面的消息交互了
總結
以上是生活随笔為你收集整理的ATS插件中配置文件自动更新思路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu 14.04 64bit上编
- 下一篇: ATS插件开发中内存泄露问题的解决方法探