鹅厂开源框架tars之运营监控服务

   tars开源框架地址:https://github.com/Tencent/Tars

系列文章:

鹅厂开源框架tars之日志服务

鹅厂开源框架tars之运营监控服务

鹅厂开源框架tars之基础组件

鹅厂开源框架tars之网络层实现

简介:Tars是腾讯从2008年到今天一直在使用的后台逻辑层的统一应用框架TAF(Total Application Framework),目前支持C++,Java,PHP,Nodejs语言。该框架为用户提供了涉及到开发、运维、以及测试的一整套解决方案,帮助一个产品或者服务快速开发、部署、测试、上线。 它集可扩展协议编解码、高性能RPC通信框架、名字路由与发现、发布监控、日志统计、配置管理等于一体,通过它可以快速用微服务的方式构建自己的稳定可靠的分布式应用,并实现完整有效的服务治理。目前该框架在腾讯内部,各大核心业务都在使用,颇受欢迎,基于该框架部署运行的服务节点规模达到上万个。

一、运维工具

鹅厂开源框架tars之运营监控服务_第1张图片

 如上图:可以清楚看到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 —业务指标统计

  1. 服务业务特性数据采集;支持平均、计数、求和、分布等统计方式
  2. 服务调用关系链采样

/**
    * 上报属性信息
    * @param statmsg, 上报信息
    * @return int, 返回0表示成功
    */
    virtual int reportPropMsg(const map& propMsg, taf::JceCurrentPtr current );

六、Registry ——主控服务:  

  1. 提供对象名称寻址服务,返回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 ——服务节点:  

  1. 同一服务器上的服务起停、服务状态信息采集、发布、配置管理、自定义消息通知。

同一服务器上的服务监控,异常退出、僵死等监控重启

        node提供的接口:

patch(patch指定服务)、stopAllServers(关闭nodes上所有服务)、

startServer(启动指定服务):

使用sFullExeFileName      //默认使用启动脚本路径 stopServer接口也是同理

getState获取指定服务状态:

   ServerObjectPtr pServerObjectPtr = ServerFactory::getInstance()->getServer( application, serverName );
    if ( pServerObjectPtr )
    {
        result += "succ";
        return pServerObjectPtr->getState();
    }

八、patch服务

——统一发布

  1. 通过web管理所有需要发布的服务和文件的目录
  2. 提供客户端(patchclient)可以从Patch服务同步文件和目录到远程
  3. 可以单独使用也可以和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 TimeLogger; TimeLogger的定义如下:

typedef TC_Logger TimeLogger;其中TC_Logger为日志基类模板:模板第一个参数TimeWriteT负责 写Logger.在applicantion服务启动的时候会调用设置远程日志服务器对象的服务:例如log=LogServer.taflog4nmrqsh2.LogObj

TafTimeLogger::getInstance()->setLogInfo(_communicator, ServerConfig::Log, ServerConfig::Application, ServerConfig::ServerName, ServerConfig::LogPath);

这里底层实现函数如下:会获取远程日志服务器的地址

鹅厂开源框架tars之运营监控服务_第2张图片

具体写日志的时候,TimeWriteT类重载了operator() ,会调用远程日志服务的logger接口写远程日志,从而实现了日志从本地到远程日志服务器的功能

_logPrx->logger(DYEING_DIR, DYEING_FILE, "day", "%Y%m%d", vDyeingLog);

 

十、WEB  — 管理平台

  1. 提供服务状态信息查询和起停服务、设置服务日志级别、发送自定义命令等操作页面
  2. 提供部署服务、自动编译发布、配置管理等运维操作页面
  3. 提供自动测试操作界面
  4. 展示服务性能指标数据
  5. 展示业务特性指标数据

 

 

 

 

 

你可能感兴趣的:(c++)