[TARS] Operación de la base de datos e hilo ReapThread en RegistryServer

0. Elicitación de preguntas de investigación

Cuando desee ver la interfaz de llamada PRC proporcionada en QueryImp, los métodos proporcionados en __tars__QueryF_all son:

static ::std::string __tars__QueryF_all[]=
{
                "findObjectById",
                "findObjectById4All",
                "findObjectById4Any",
                "findObjectByIdInSameGroup",
                "findObjectByIdInSameSet",
                "findObjectByIdInSameStation"
};

Solo mire el código D: \ 005-02-code \ 016-TARS \ TARS \ TarsFramework \ RegistryServer \ QueryImp.cpp, para las variables miembro estáticas

La fuente del valor de CDbHandle :: _ objectsCache será un poco confusa, hasta que busqué [loadObjectIdCache] globalmente y encontré que

En ReapThread de RegistryServer, esto se llamará en el proceso de ReapThread :: init () y ReapThread :: run ()

CDbHandle :: loadObjectIdCache este método, y este método llamará CDbHandle :: updateObjectsCache comprobará desde la base de datos

El resultado de la consulta se actualiza a variables miembro estáticas como _objectsCache. Aquí, la operación de la base de datos en RegistryServer y el hilo ReapThread se actualizan.

Realiza algunos estudios de investigación y explicaciones de contenido relacionado.

1. Descripción de clases relacionadas

1.1 Clase de operación de base de datos CDbHandle

// 数据库操作类
class CDbHandle
{
private:
    struct GroupPriorityEntry
    {
        std::string        sGroupID;
        std::string        sStation;
        std::set<int>     setGroupID;
    };
    enum GroupUseSelect
    {
        ENUM_USE_WORK_GROUPID,
        ENUM_USE_REAL_GROUPID
    };
    //set中服务的信息
    struct SetServerInfo
    {
        string     sSetId;
        string     sSetArea;
        bool       bActive;
        EndpointF  epf;
    };
    typedef map<string,map<string,vector<CDbHandle::SetServerInfo> > > SetDivisionCache; // <servant,setname,vector>

public:
    CDbHandle(): _enMultiSql(false){} // 构造函数
    int init(TC_Config *pconf);// 初始化
    NodePrx getNodePrx(const string & nodeName);// 获取特定node id的对象代理
    int registerNode(const string & name, const NodeInfo & ni, const LoadInfo & li);// 保存node注册的session
    int destroyNode(const string & name);// 更新node的状态为inactive
    int keepAlive(const string & name, const LoadInfo & li);// 更新node心跳时间及机器负载
    map<string, string> getActiveNodeList(string & result);// 获取活动node列表endpoint信息
    int getNodeVersion(const string &nodeName, string &version, string & result);// 获取node版本
    vector<ServerDescriptor> getServers(const string & app, const string & serverName, const string & nodeName, bool withDnsServer = false);// 获取在该node部署的server列表
    string getProfileTemplate(const string & sTemplateName, string & sResultDesc);// 获取server的配置模板

protected: 
    string getProfileTemplate(const string & sTemplateName, map<string, int> & mapRecursion, string & sResultDesc);// 获取server的配置模板

public:
    // 更新server状态
    int updateServerState(const string & app, const string & serverName, const string & nodeName, const string & stateFields, ServerState state, int processId = -1);
    int updateServerStateBatch(const std::vector<ServerStateInfo> & vecStateInfo);// 批量更新server状态
    vector<EndpointF> findObjectById(const string & id);// 根据id获取对象
    // 根据id获取对象
    int findObjectById4All(const string & id, vector<EndpointF>& activeEp, vector<EndpointF>& inactiveEp);
    // 根据id获取同组对象
    int findObjectByIdInSameGroup(const string & id, const string & ip, vector<EndpointF>& activeEp, vector<EndpointF>& inactiveEp, ostringstream &os);
    // 根据id获取优先级序列中的对象
    int findObjectByIdInGroupPriority(const std::string &sID, const std::string &sIP, std::vector<EndpointF> & vecActive, std::vector<EndpointF> & vecInactive, std::ostringstream & os);
    //根据id和归属地获取全部对象
    int findObjectByIdInSameStation(const std::string &sID, const std::string & sStation, std::vector<EndpointF> & vecActive, std::vector<EndpointF> & vecInactive, std::ostringstream & os);
    // 根据id和set信息获取全部对象
    int findObjectByIdInSameSet(const string &sID, const vector<string> &vtSetInfo, std::vector<EndpointF> & vecActive, std::vector<EndpointF> & vecInactive, std::ostringstream & os);
    // 根据setId获取全部对象
    int findObjectByIdInSameSet(const string &sSetId, const vector<SetServerInfo>& vSetServerInfo, std::vector<EndpointF> & vecActive, std::vector<EndpointF> & vecInactive, std::ostringstream & os);
    vector<string> getAllApplicationNames(string & result);// 获取application列表
    vector<vector<string> > getAllServerIds(string & result);// 获取server列表
    int getConfig(const string &appServerName, const string &fileName, const string &host, string &config, std::string &resultDesc);// 获取合并的配置文件
    int setPatchInfo(const string & app, const string & serverName, const string & nodeName, const string & version, const string & user);// 设置server发布版本
    int setServerTarsVersion(const string & app, const string & serverName, const string & nodeName, const string & version);// 设置server的tars库版本
    int checkNodeTimeout(unsigned uTimeout);// 轮询数据库,将心跳超时的节点及server状态设为不存活
    int checkRegistryTimeout(unsigned uTimeout);// 轮询数据库,将心跳超时的registry设为不存活
    int checkSettingState(const int iCheckLeastChangedTime=3600);// 定时检查在数据库的设置状态为“active”的服务在Node节点上的状态:如果服务在Node的设置状态不是“active”,则通知Node主动重启该服务
    int computeInactiveRate();// 在加载对象列表之前,计算当前非活动状态的node的比率
    int loadObjectIdCache(const bool bRecoverProtect, const int iRecoverProtectRate, const int iLoadTimeInterval=60, const bool bLoadAll=false, bool fromInit = false);// 加载对象列表到内存
    int loadGroupPriority(bool fromInit);// 加载组优先级到内存
    int updateRegistryInfo2Db(bool bRegHeartbeatOff=false);// 更新registry信息到db
    int getNodeTemplateName(const string nodeName, string & sTemplateName);// 获取对应node的模板名称
    int getGroupId(const string& ip);// 根据ip获取组id
    int getGroupIdByName(const string& sGroupName);// 根据组名获取组id
    int loadIPPhysicalGroupInfo(bool fromInit);// 加载IP物理分组信息
    static uint32_t stringIpToInt(const std::string& sip);// ip转换
    static string Ip2Str(uint32_t ip);// ip转换
    static string Ip2StarStr(uint32_t ip);// ip转换

protected:
    vector<EndpointF> getEpsByGroupId(const vector<EndpointF> & vecEps, const GroupUseSelect GroupSelect, int iGroupId, ostringstream &os);// 根据group id获取Endpoint
    vector<EndpointF> getEpsByGroupId(const vector<EndpointF> & vecEps, const GroupUseSelect GroupSelect, const set<int> & setGroupID, ostringstream & os);// 根据group id获取Endpoint
    int doUpdateServerStateBatch(const std::vector<ServerStateInfo> & vecStateInfo, const size_t sizeBegin, const size_t sizeEnd);// updateServerStateBatch的底层实现函数

private:
    void updateStatusCache(const std::map<ServantStatusKey, int>& mStatus,bool updateAll=false);// 更新缓存中的服务状态值
    void updateObjectsCache(const ObjectsCache& objCache,bool updateAll=false);// 更新缓存中的服务信息
    void updateDivisionCache(const SetDivisionCache& setDivisionCache,bool updateAll=false);// 更新缓存中的set信息
    TC_Mysql::MysqlData UnionRecord(TC_Mysql::MysqlData& data1,TC_Mysql::MysqlData& data2);// 对数据库查询结果执行联合操作
    void sendSqlErrorAlarmSMS(const string &err);// 数据库访问异常上报
    void load2GroupMap(const vector<map<string,string> >& serverGroupRule);// 建立ip分组map

protected:
    bool _enMultiSql;//是否允许采用多条语句同时执行方式
    TC_Mysql _mysqlReg;//mysql连接对象
    static map<string , NodePrx> _mapNodePrxCache; //node节点代理列表
    static TC_ThreadLock _NodePrxLock;
    static TC_ReadersWriterData<ObjectsCache>    _objectsCache;//对象列表缓存
    static TC_ReadersWriterData<SetDivisionCache> _setDivisionCache;//set划分缓存
    static TC_ReadersWriterData<std::map<int, GroupPriorityEntry> > _mapGroupPriority;//优先级的序列
    static std::map<ServantStatusKey, int> _mapServantStatus; //servant状态表 
    static TC_ThreadLock _mapServantStatusLock;//存在多线程更新_mapServantStatus,需要加锁   
    static TC_ReadersWriterData<map<string,int> > _groupIdMap;//分组信息
    static TC_ReadersWriterData<map<string,int> > _groupNameMap;
};

1.2 La clase de hilo ReapThread utilizada para realizar operaciones de cronometraje

// 用于执行定时操作的线程类
class ReapThread : public TC_Thread, public TC_ThreadLock
{
public:
    ReapThread(); // 构造函数
    ~ReapThread(); // 析构函数
    void terminate(); // 结束线程
    int init(); // 初始化
    virtual void run(); // 轮询函数
protected:
    bool       _terminate; // 线程结束标志
    CDbHandle  _db; // 数据库操作
    int        _loadObjectsInterval1; // 加载对象列表的时间间隔,单位是秒
    int        _leastChangedTime1; // 第一阶段加载时间 consider
    int        _loadObjectsInterval2; //  全量加载时间,单位是秒
    int        _leastChangedTime2; // 
    int        _registryTimeout;// registry心跳超时时间
    bool       _recoverProtect; // 是否启用DB恢复保护功能,默认为打开
    int        _recoverProtectRate;// 启用DB恢复保护功能状态下极限值
    bool       _heartBeatOff;// 主控心跳时间更新开关
};

2. Análisis específico

2.1 CDbHandle :: loadObjectIdCache

CDbHandle::loadObjectIdCache这个函数中更新了
_objectsCache
_mapServantStatus
_setDivisionCache
这三个CDbHandle类的静态成员变量的值.

/**
* 加载对象列表到内存
* @param bRecoverProtect
* @param iRecoverProtectRate
* @param iLoadTimeInterval 加载最近iLoadTimeInterval秒内变化的记录
* @param bLoadAll  是否加载所有服务
* @param bFirstLoad  是否是第一次全量加载
* @param fromInit 是否来着初始化的调用
* @return
*/
 int loadObjectIdCache
(const bool bRecoverProtect, 
 const int iRecoverProtectRate, 
 const int iLoadTimeInterval=60, 
 const bool bLoadAll=false, 
 bool fromInit = false);


int ReapThread::init()
{
...
   _db.loadObjectIdCache(_recoverProtect, _recoverProtectRate,0,true, true);
...
}

int ReapThread::run()
{
  ...
  if(tNow - tLastLoadObjectsStep2 >= _loadObjectsInterval2)
  {
     tLastLoadObjectsStep2 = tNow;
     //全量加载,_leastChangedTime2参数没有意义
     _db.loadObjectIdCache(_recoverProtect, _recoverProtectRate,_leastChangedTime2,true, false);
   }
   else
   {
       _db.loadObjectIdCache(_recoverProtect, _recoverProtectRate,_leastChangedTime1,false, false);
   }
  ...
}

 

Supongo que te gusta

Origin blog.csdn.net/Edidaughter/article/details/115190278
Recomendado
Clasificación