1、服务状态更新频率 是在<reap>段 的配置内。
<reap>
#服务心跳更新时间(s) 此值在代码里有最小保护为5s 配置小于5s时 自动设置成5s
updateHeartInterval=15
#主控心跳超时检测时间,单位是秒..代码最小值保护为5s
registryTimeout=150
#主控心跳关闭开关,默认允许心跳检测,要迁移的时候设置次项为N
# heartbeatoff=Y
</reap>
heartbeatoff这个实现应该很有意思。。迁移机房时候处理方式
2、主控启动时候及心跳时的处理
主控信息存在 t_registry_info 启服时 。执行下面的load信息事务:
更新主控自己在t_registry_info中对应的present_state置为activity 另写入当前时间为心跳时间
从t_server_group_rule中更新物理ip规则,这个东东包括了分组id,分组名,允许ip,禁止ip这些信息。这些东东,就成为了实现set分组的基础
心跳是定时线程 每100ms检测一次。执行上面的load信息事务。
另外心跳还要做,遍历table中的所有register,如果有register超时,则将t_registry_info中present_state置为inactive。超时时间是上面<reap>中配置的,不过不能小于5s。
3、任务列表部分的处理方式
1)这里的任务定义为?
db里存任务列表信息。。内存里存一份任务列表
2)在添加任务时,创建任务(分串行,并行 任务两种);将任务添加入内存中的任务列表;遍历任务列表,将超过2天的任务从列表中移除;执行此任务。
3)有定时器每隔5s一次,将创建超过2分钟的任务 从内存任务列表中移除(完全看不懂这是啥意思)..
4)执行任务时,串行任务 按参数中传过来顺序执行,并行任务 扔进自己的线程池里执行,线程池内线程数默认为任务数,但不超过10个.执行前和执行完毕 对应更改任务状态,并保存到db中
这里对线程池的用法很简洁,可以学习下:
for (size_t i=0; i < _taskReq.taskItemReq.size(); i++)
{
auto cmd = std::bind(&TaskListParallel::doTask, this, _taskReq.taskItemReq[i], i);
_pool.exec(cmd);
}
5)然后执行对应的 start,restart,stop,patch,undeploy,gridPatchServer等具体任务。
4、patch流程
关于patch的流程多一点.先batchPatch发布;再循环1s 调用getPatchPercent获取发布中的进度;进度返回值表示失败或者发布100%完成,则updatePatchLog写入发布日志更新发布状态。如果获取进度时try-catch异常或者正常进度则继续循环(这个异常处理挺有意思)。
batchPatch的流程为:
1]通过req.version 从t_server_patchs中获取 包名 和 md5 ;
2]调用patchServer的 preparePatchFile 准备好包文件,将发布的文件从上传目录复制到发布目录;
3]根据node名,从t_node_info 中找到对应的Node名,并生成对应的NodePrx对象。
4]设置patch超时时间,默认为10s,异步调用NodeServer的patchPro 开始发布。patchPro 的实现参考NodeServer部分文档..
5]发布过程中的异常通过回调及try-catch中实现记录下了。上面流程执行失败,都会中断流程,直接返回。 此处关于异步回调,设定超时回调方式的写法 可以参考下
getPatchPercent的流程简单,直接向NodeServer调用getPatchPercent异步拉取进度值
updatePatchLog则是将进度数据写入 t_server_patchs 表
5、startServer流程
1]设置db t_server_conf 中的服务状态为Active.
2]从t_server_conf中重拉取服务信息.
3]判断是否是tars_dns 服务;如果是tars_dns服务,忽略启动请求并将其present_state置位Active,其它服务则调用NodeServer的startServer进行服务重启。
完全看不懂,tars_dns这个系列服务是啥概念??为啥这么多操作上都特殊处理?
6、stopServer流程
1]设置db t_server_conf 中的服务状态为Inactive.
2]从t_server_conf中重拉取服务信息.
3]判断是否是tars_dns 服务;如果是tars_dns服务,忽略启动请求并将其present_state置位Inactive,其它服务则调用NodeServer的stopServer停掉服务。
7、restartServer流程
先给NodeServer发stopServer。成功后再执行上面的startServer流程
8、undeploy删除服务流程
直接把 t_server_conf 和 t_adapter_conf表中对应字段删除..所以执行undeploy之前 需要先停服,不然NodeServer那边是不知道节点已被下线的。
9、notifyServer 通知server
推配置给服务就会用到此函数。通知指定的NodeServer->notifyServer()
10、gridPatchServer灰度发布接口
函数的说明就是自动伸缩时调用的灰度发布接口。
貌似就把db里面的server状态改成灰度状态 就没干啥了。这个灰度的玩法 其实是找几个机器,在t_server_conf的grid_flag字段做下标记表示是灰度机,主控根据grid来拉不同的节点,在服务obj配置里加上-g 来标识你要起用grid。其实就是个set分组的用法,此链路上的服务,只跟自己链路内服务交互,实现隔离测试的目的。大佬们表示,其实还是自己搞个set来搞这个更方便点。
貌似tars并没有实现此功能??
11、对node管理的一些接口汇总
这些操作的node节点都是通过一个node id去指定
getAllNodeNames..
pingNode 对node节点发ping。。3s超时.
shutdownNode 停掉指定的node.
getNodeVesion ...
getClientIp..node通过接口获取连接上主控的node ip
我很惊奇的发现..t_server_conf中的node_name是varchar(50),而t_node_info中的node_name是varchar(128).id是int(11)。完全看不懂为啥这么设计??
11、对服务管理的一些接口汇总
getAllServerIds..把全部服务的相关信息从db中读取出来,结果用vector<string>返回
getServerState..get指定服务的信息,先读t_server_conf 中的server信息,如果非tars_dns服务,再去NodeServer->getStateInfo获取最新的serverstate
getGroupId..获取某ip所属group 用于机房部署 例如某ip属于那个机房
startServer..
stopServer..
restartServer..
notifyServer..
undeploy..
batchPatch..
updatePatchLog..发布任务执行完之后,更新发布状态的到db.
getPatchPercent..获取发布进度..
loadServer..通知指定的NodeServer加载指定的server..
getProfileTemplate..从t_profile_template中获取指定模板名称相关的模板内容,用字符串返回
一些注意点
除了startServer,stopServer,notifyServer,batchPatch这些流程外。主控接口代码还算比较简单。这些接口中,拉取节点信息或任务信息,是内部的cache数据外,拉其它数据接口 基本上都是读db来获取(为了防止脏数据?)。