xxl-job 服务端自动注册逻辑梳理

344 阅读2分钟

服务端自动注册到管理端

服务端启动

ExecutorRegistryThread 类的守护线程自动上报到管理端

registryThread = new Thread(new Runnable() {
    @Override
    public void run() {
        while (!toStop) {
            RegistryParam registryParam = new RegistryParam(RegistryConfig.RegistType.EXECUTOR.name(), appname, address);
            //遍历所有客户端列表
            for (AdminBiz adminBiz: XxlJobExecutor.getAdminBizList()) {
                try {
                //调用端接口进行注册
                    ReturnT<String> registryResult = adminBiz.registry(registryParam);
                    if (registryResult!=null && ReturnT.SUCCESS_CODE == registryResult.getCode()) {
                        //... 成功
                        registryResult = ReturnT.SUCCESS;
                        break;
                    } else {
                        //...失败
                    }
                } catch (Throwable e) {
                    //异常处理
                }
            }
        }
    }
});

管理端接受注册方法

com.xxl.job.admin.controller.JobApiController#api

@RequestMapping("/{uri}")
@ResponseBody
@PermissionLimit(limit=false)
public ReturnT<String> api(HttpServletRequest request, @PathVariable("uri") String uri, @RequestBody(required = false) String data) {
    // services mapping
    if ("registry".equals(uri)) {
        RegistryParam registryParam = GsonTool.fromJson(data, RegistryParam.class);
        return adminBiz.registry(registryParam);
    } 
}

com.xxl.job.admin.core.thread.JobRegistryHelper#registry

registryGroup : EXECUTOR
registryKey:appname
registryValue:address(服务端地址带端口)

public ReturnT<String> registry(RegistryParam registryParam) {

   // async execute
   registryOrRemoveThreadPool.execute(new Runnable() {
      @Override
      public void run() {
         // 0-fail; 1-save suc; 2-update suc;
         int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registrySaveOrUpdate(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date());
         if (ret == 1) {
            // fresh (add)
            freshGroupRegistryInfo(registryParam);
         }
      }
   });

   return ReturnT.SUCCESS;
}
<insert id="registrySaveOrUpdate" >
   INSERT INTO xxl_job_registry( `registry_group` , `registry_key` , `registry_value`, `update_time`)
   VALUES( #{registryGroup}  , #{registryKey} , #{registryValue}, #{updateTime})
   ON DUPLICATE KEY UPDATE
      `update_time` = #{updateTime}
</insert>

客户端自动刷新

JobRegistryHelper
XxlJobRegistry中删除掉9秒为未更新的数据,XxlJobRegistry表剩下的数据更新xxlJobGroup

registryMonitorThread = new Thread(new Runnable() {
   @Override
   public void run() {
      while (!toStop) {
         try {
            // auto registry group 执行器信息表,维护任务执行器信息;  // 执行器地址类型:0=自动注册、1=手动录入
            List<XxlJobGroup> groupList = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().findByAddressType(0);
            if (groupList!=null && !groupList.isEmpty()) {
               // remove dead address (admin/executor) 查询90秒未更新的 xxl_job_registry (执行器注册表,维护在线的执行器和调度中心机器地址信息;) XxlJobRegistry
               List<Integer> ids = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findDead(RegistryConfig.DEAD_TIMEOUT, new Date());
               //xxl_job_registryb表中删除 90秒未更新的
               if (ids!=null && ids.size()>0) {
                  XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().removeDead(ids);
               }
               // fresh online address (admin/executor) 管理端appName List<管理端地址>
               HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>();
               //查询所有存活的 xxl_job_registry数据
               List<XxlJobRegistry> list = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
               //收集执行器executor 的 xxl_job_registry value数据
               if (list != null) {
                  for (XxlJobRegistry item: list) {
                     if (RegistryConfig.RegistType.EXECUTOR.name().equals(item.getRegistryGroup())) {
                        String appname = item.getRegistryKey();
                        List<String> registryList = appAddressMap.get(appname);
                        if (registryList == null) {
                           registryList = new ArrayList<String>();
                        }
                        if (!registryList.contains(item.getRegistryValue())) {
                           registryList.add(item.getRegistryValue());
                        }
                        appAddressMap.put(appname, registryList);
                     }
                  }
               }
               // fresh group address 更新 xxlJobGroup 信息
               for (XxlJobGroup group: groupList) {
                  List<String> registryList = appAddressMap.get(group.getAppname());
                  String addressListStr = null;
                  if (registryList!=null && !registryList.isEmpty()) {
                     //地址排序
                     Collections.sort(registryList);
                     StringBuilder addressListSB = new StringBuilder();
                     for (String item:registryList) {
                        addressListSB.append(item).append(",");
                     }
                     addressListStr = addressListSB.toString();
                     addressListStr = addressListStr.substring(0, addressListStr.length()-1);
                  }
                  group.setAddressList(addressListStr);
                  group.setUpdateTime(new Date());
                  XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().update(group);
               }
            }
         } catch (Throwable e) {
            if (!toStop) {
               logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e);
            }
         }
         try {
            TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT);
         } catch (Throwable e) {
            if (!toStop) {
               logger.error(">>>>>>>>>>> xxl-job, job registry monitor thread error:{}", e);
            }
         }
      }
      logger.info(">>>>>>>>>>> xxl-job, job registry monitor thread stop");
   }
});