鵝廠開源框架tars之運營監控服務
一、運維工具
如上圖:可以清楚看到tar框架的運維服務和工具:包括主控Resistry、配置檔案中心Config、異常資訊Nofify、指標統計Stat、遠端log、釋出平臺Patch、業務資訊Property等主要服務,再結合web平臺來對這些服務進行視覺化操作和運用,對開發和運維人員算是非常方便和人性化了
二、配置中心 config 服務
config服務用於提供整套框架的配置檔案儲存和讀取等操作;後臺使用mysql儲存
使用例子:
addAppConfig("DBConnection.conf"); //新增應用級別的配置檔案
呼叫TafRemoteConfig::getInstance()->addConfig(filename, result, true)函式:
addConfig函式呼叫getRemoteFile函式遠端從config server獲取配置檔案資訊:
rpc呼叫:_configPrx->loadConfig(_sApp, (bAppConfigOnly ? "" : _sServerName), sFileName, stream);
跳轉到:Config server 的介面函式ConfigImp::loadConfig 函式,如果是應用級別的配置檔案:則執行“”select id,config from t_config_files...“” 並且把結果使用string的方式回傳給呼叫者
呼叫者獲取到檔案內容,根據檔案的名字生成在本地以供後續程式使用檔案:std::ofstream out(newFile.c_str());
addConfig(ServerConfig::ServerName + ".conf"); //添加當前程序所在的本地檔案
呼叫:TafRemoteConfig::getInstance()->addConfig(filename, result, false) 注意:最後一個引數bAppConfigOnly設定為false,
呼叫int ret = _configPrx->loadConfig(_sApp, (bAppConfigOnly ? "" : _sServerName), sFileName, stream); 可見和載入應用級別的配置檔案有所不同,這裡呼叫_configPrx伺服器的引數,增加了_sServerName。則rpc呼叫loadConfig介面的時候伺服器引數不為空,改掉用loadConfigByHost:同樣通過mysql查詢t_config_files表格但增加了where查詢條件"where server_name = '" + _mysqlConfig.escapeString(appServerName)。至此,實現了從指定伺服器拉取配置檔案的功能 (這裡還關係到引用配置等功能,多個同名檔案還涉及到檔案合併等,這裡先不做詳細說明)
三、Nofify服務,官方文件定義為異常資訊。輸出的資訊可以在tars運營平臺裡面看到
TafRemoteNotify::getInstance()->report("[info]: white list open for ["+ _sUinList + "]");
原始碼實現:
if(_notifyPrx)
{
if(!bSync)
{
_notifyPrx->async_reportServer(NULL, _sApp + "." + _sServerName, TC_Common::tostr(pthread_self()), sResult);
}
else
{
_notifyPrx->reportServer(_sApp + "." + _sServerName, TC_Common::tostr(pthread_self()), sResult);
}
}
Nofify 服務實現,主要就是把資料插入t_server_notifys_資料庫。這裡預設都是使用非同步的介面,否則估計效率容易有問題,畢竟是直接操作db
string sql;
TC_Mysql::RECORD_DATA rd;
rd["server_name"] = make_pair(TC_Mysql::DB_STR, sServerName);
rd["server_id"] = make_pair(TC_Mysql::DB_STR, sServerName + "_" + current->getIp());
rd["thread_id"] = make_pair(TC_Mysql::DB_STR, sThreadId);
rd["result"] = make_pair(TC_Mysql::DB_STR, sResult);
rd["notifytime"] = make_pair(TC_Mysql::DB_INT, "now()");
string sTable = "t_server_notifys_" + TC_Common::tm2str(TNOW,"%Y%m%d");
try
{
_mysqlConfig.insertRecord(sTable, rd);
四、Stat服務——效能指標統計
服務效能資料採集:呼叫時間、成功次數、超時次數、異常次數、耗時分佈等資訊。服務間呼叫關係鏈取樣。
Stat服務介面:reportProxyMicMsg:udp上報模組間呼叫取樣資訊
五、Property —業務指標統計
- 服務業務特性資料採集;支援平均、計數、求和、分佈等統計方式
- 服務呼叫關係鏈取樣
/**
* 上報屬性資訊
* @param statmsg, 上報資訊
* @return int, 返回0表示成功
*/
virtual int reportPropMsg(const map<StatPropMsgHead,StatPropMsgBody>& propMsg, taf::JceCurrentPtr current );
六、Registry ——主控服務:
- 提供物件名稱定址服務,返回IP:Port列表;為客戶端提供可用服務列表資訊
提供TAF框架核心管理功能 :服務部署、服務起停、服務狀態資訊查詢、釋出、配置管理、命令通知
Registry 提供registerNode(node節點註冊)、keepAlive(node上報心跳負載)、getServers(獲取在該node部署的server列表)、updateServer(更新server狀態)、
同時主控提供了AdminRegImp(關聯控制介面類),提供如下介面:
getAllApplicationNames(獲取application列表)、getAllNodeNames(獲取node列表)、shutdownNode(停止 node)、getServerState(獲取特定server狀態)、startServer(啟動特定server)、restartServer( 重啟特定server)、notifyServer(通知服務)、patchServer(釋出特定server)
例子:startServer介面實現
//更新資料庫server的設定狀態
_db.updateServerState(application, serverName, nodeName, "setting_state", taf::Active);
判斷是否為dns:
DNS: 通過db修改
iRet = _db.updateServerState(application, serverName, nodeName, "present_state", taf::Active);
非DNS:通過node節點啟動(下面介紹node節點的作用)
NodePrx nodePrx = _db.getNodePrx(nodeName);
iRet = nodePrx->startServer(application, serverName, result);
七、Node ——服務節點:
- 同一伺服器上的服務起停、服務狀態資訊採集、釋出、配置管理、自定義訊息通知。
同一伺服器上的服務監控,異常退出、僵死等監控重啟
node提供的介面:
patch(patch指定服務)、stopAllServers(關閉nodes上所有服務)、
startServer(啟動指定服務):
使用sFullExeFileName //預設使用啟動指令碼路徑 stopServer介面也是同理
getState獲取指定服務狀態:
ServerObjectPtr pServerObjectPtr = ServerFactory::getInstance()->getServer( application, serverName );
if ( pServerObjectPtr )
{
result += "succ";
return pServerObjectPtr->getState();
}
八、patch服務
——統一發布
- 通過web管理所有需要釋出的服務和檔案的目錄
- 提供客戶端(patchclient)可以從Patch服務同步檔案和目錄到遠端
- 可以單獨使用也可以和node配合使用完成釋出動作
listFileInfo(獲取路徑下所有檔案列表資訊)、download(下載檔案)
九、Taf-Log ——日誌中心
日誌伺服器,用於接收遠端日誌。業務服務以框架層的api非同步傳送日誌到日誌伺服器
例子:
#define LOG_STAT(type) FDLOG(type)
其中FDLOG的定義在庫檔案的taf_logger.h定義如下:
#define FDLOG(x) (TafTimeLogger::getInstance()->logger(x)->any())
TafTimeLogger::getInstance()->logger(x)函式生成並返回:TimeLogger
typedef TC_Logger<TimeWriteT, TC_RollByTime> TimeLogger; TimeLogger的定義如下:
typedef TC_Logger<TimeWriteT, TC_RollByTime> TimeLogger;其中TC_Logger為日誌基類模板:模板第一個引數TimeWriteT負責 寫Logger.在applicantion服務啟動的時候會呼叫設定遠端日誌伺服器物件的服務:例如log=LogServer.taflog4nmrqsh2.LogObj
TafTimeLogger::getInstance()->setLogInfo(_communicator, ServerConfig::Log, ServerConfig::Application, ServerConfig::ServerName, ServerConfig::LogPath);
這裡底層實現函式如下:會獲取遠端日誌伺服器的地址
具體寫日誌的時候,TimeWriteT類過載了operator() ,會呼叫遠端日誌服務的logger介面寫遠端日誌,從而實現了日誌從本地到遠端日誌伺服器的功能
_logPrx->logger(DYEING_DIR, DYEING_FILE, "day", "%Y%m%d", vDyeingLog);
十、WEB — 管理平臺
- 提供服務狀態資訊查詢和起停服務、設定服務日誌級別、傳送自定義命令等操作頁面
- 提供部署服務、自動編譯釋出、配置管理等運維操作頁面
- 提供自動測試操作介面
- 展示服務效能指標資料
- 展示業務特性指標資料