改了配置,不想重啟,怎么整?
有個水友在知識星球提問:沈老師,我們有個連接超時的配置,平時是300毫秒,雙11壓力上來了,數據庫變慢了,平均請求處理時間增加到了500毫秒,于是我們決定將連接超時改為1000毫秒,但這個過程需要重啟服務,會影響正在執行的請求。有什么好辦法,不重啟服務,就能夠修改配置么?
不妨設,讀取與設置超時的偽代碼如下:
- // 從配置文件中讀取超時配置
- timeout = CGlobalConf::readFileConf(“timeout”);
- // 設置請求超時閾值
- CConnectionPool::setTimeout(timeout);
不重啟服務,重新載入配置的常見方式有3這么幾種,不難但很使用,花1分鐘和大家說一說。
方案一:發信號觸發配置重載
這種方法無需加入任何組件,新增一個信號捕捉函數,來處理配置的重新載入。
- // 服務啟動時,設置ctrl+c回調函數
- signal(SIGINT, sigint_shenjian_process);
- // 捕獲ctrl+c時,執行配置重新載入動作
- void sigint_shenjian_process(int){
- //從配置中讀取超時配置
- timeout= CGlobalConf::readFileConf(“timeout”);
- //設置請求超時閾值
- CConnectionPool::setTimeout(timeout);
- }
當需要變更配置時,只需要:
- 修改配置文件;
- 發送信號,觸發配置重新載入;
畫外音:啥,不知道如何向服務發信號?
方案二:檢測配置文件變化,自動重新載入
這種方法無需手動發送信號,修改完配置文件,自動檢測,自動載入,需要加入文件監控組件。
畫外音:這類組件開源的也不少。
文件監控組件如何能監控文件的變化呢?
別想復雜了,可以定期檢查文件的md5或者last_modify_time。
- // 服務啟動時,初始化
- CFileMonitor::init(){
- // 獲取初始md5
- old_md5=xxx;
- }
- // 啟動一個進程,監控文件變化
- CFileMonitor::start(){
- while(1){ // 循環檢查
- // 獲取最新md5
- now_md5=xxx;
- // 比對md5是否變化,如果變化
- if(now_md5!=old_md5){
- //從配置中讀取超時配置
- timeout= CGlobalConf::readFileConf(“timeout”);
- //設置請求超時閾值
- CConnectionPool::setTimeout(timeout);
- //修改md5
- old_md5=now_md5;
- }
- // 一秒后再檢查
- sleep(1000);
- }
- }
方案三:配置中心,配置變化時回調
次方案拋棄了配置文件,需要引入配置中心:
- 所有服務從配置中心拿配置;
- 必須從配置中心后臺修改配置;
- 配置修改,配置中心回調引用了相關配置的服務;
- // 服務啟動時,從配置中心獲取配置,并注冊回調函數
- timeout = CConfCenter::(“timeout”, callback_shenjian);
- // 設置請求超時閾值
- CConnectionPool::setTimeout(timeout);
- void callback_shenjian(timeout){
- //在配置中心修改配置時,會收到回調
- CConnectionPool::setTimeout(timeout);
- }
修改配置,不重啟服務,上面三種方式都很常見,不難但實用。
畫外音:特別是前兩種方式,瞬間就能實現。
希望大家有收獲。
【本文為51CTO專欄作者“58沈劍”原創稿件,轉載請聯系原作者】