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);
}
...
}