zoukankan      html  css  js  c++  java
  • tars framework 源码解读(五) framework 部分章节。主控 AdminRegistryServer

    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来获取(为了防止脏数据?)。

  • 相关阅读:
    ==和equals
    Fastjson toJSONString 碰到的一个问题
    Java之旅之第一个Java项目[Sping+ Spring MVC + MyBatis] 项目框架
    Java之旅之第一个Java项目[Sping+ Spring MVC + MyBatis] 项目配置
    Java之旅之第一个Java项目[Sping+ Spring MVC + MyBatis] org.springframework.web相关源码
    Java之旅之第一个Java项目[Sping+ Spring MVC + MyBatis] 项目背景
    centos6 yum源不可用问题解决
    ORACLE修改最大连接数
    Docker学习笔记(二):Docker镜像
    Mysql5.7慢日志时间与系统时间相差8小时问题的解决
  • 原文地址:https://www.cnblogs.com/yylingyao/p/12198381.html
Copyright © 2011-2022 走看看