server 与 worker 之间通过 ****HTTP+JSON 进行通讯,开发者基于 Http 实现每个语言具体的 client。
PowerJob 在设计中,任务的执行是 worker 高度自治的,server 只做一开始的任务派发和后续的状态检测,因此需要实现的规范很少。
推荐先阅读官方的 powerjob-worker Java 版,无论是与 server 的交互还是 worker 内部任务的执行,思路大体上都是一致的。
没有特别约定返回值的请求,可随意返回结果字段,比如 "success"
postman: LINK
简单版:HTTP
复活:HttpProcessor
- 主要是考虑到开发一个 client 还是有一定成本的(开发 + 维护)
- 官方仅提供 Java & Python 双 client
完全体:Client
初始化阶段
初始化阶段的所有请求用的都是配置文件中配置的服务器地址(默认为 7700)端口
也只有这两个请求用的是配置文件中的服务器地址
App 校验
校验该 App 是否已在 server 端注册
请求地址:/server/assert?appName=
请求方式:GET
返回值:
{
"success":true, // true 代表校验通过,false 代表校验不通过,此时应该阻止应用继续启动
"data":1, // 该 appName 对应的 appId,需要保存该值,后续所有请求都依赖 appId
"message":"" // success 为 false 时存在,代表错误信息
}
Java 版代码路径:tech.powerjob.worker.PowerJobWorker#assertAppName
服务发现
定时请求 server 获取当前 app 真正的调度服务器地址,所有 worker 的请求都通过该返回地址发送。
请求地址:/server/acquire?appId=%d¤tServer=%s&protocol=HTTP
- appId 处填入之前返回的 appId
- currentServer 填当前使用的调度服务器地址,初次请求时可不填
- clientVersion:客户端版本
请求方式:GET
返回值
{
"success":true,
"data":"127.0.0.1:10010", // 当前该 app 所使用的 server 地址,需要保存下来,后续所有请求都通过该地址发送给 server
"message":""
}
Java 版代码路径:tech.powerjob.worker.background.ServerDiscoveryService#acquire
注意:
- 该接口极其重要,为了保证高可用性,需要定时请求以获取 server 的最新地址
- 该接口返回的地址才是 worker 真正需要交互的 server address,因此该返回值必须保存下来且可被 worker 读取并使用
处理 Server 请求
任务执行请求
当 server 调度任务执行时,会发送该请求到 worker,worker 需要接收并解析该请求,并完成任务的运行。
worker 需要提供符合预期的 HTTP 接口来接收 server 的请求:
- 接口地址:/worker/runJob
- 请求方式:POST
- 请求参数
-
- 官方文档更新可能不及时,建议直接参考对象
tech.powerjob.common.request.ServerScheduleJobReq
- 官方文档更新可能不及时,建议直接参考对象
{
"allWorkerAddress": ["192.168.1.9:27777", "192.168.1.9:27778"],
"jobId": 202,
"wfInstanceId": null,
"instanceId": 241521139652755520,
"executeType": "STANDALONE",
"processorType": "EMBEDDED_JAVA",
"processorInfo": "cn.edu.zju.oms.container.SimpleStandaloneProcessor",
"instanceTimeoutMS": 0,
"jobParams": "{"batchSize": 10, "batchNum": 10}",
"instanceParams": null,
"threadConcurrency": 5,
"taskRetryNum": 1,
"timeExpressionType": "API",
"timeExpression": null,
"maxInstanceNum": 0
}
- allWorkerAddress:Array类型,代表可参与本次任务运行的所有 worker 地址
- executeType:执行类型,STANDALONE / BROADCAST / MAP_REDUCE / MAP
- instanceId:任务实例ID
- instanceTimeoutMS:任务超时时间
- jobId:任务ID
- jobParams:任务的控制台参数
- maxInstanceNum:任务的最大实例数
- processorInfo:任务的处理器信息
- processorType:任务的处理器类(其他语言的客户端可以直接忽略这个属性)
- taskRetryNum:最大 Task 重试次数
- threadConcurrency:线程并发数
- timeExpression:时间表达式内容,由 timeExpressionType 决定具体的值类型,可能是数字(秒级任务)
- timeExpressionType:时间表达式类型,API / CRON / FIXED_RATE / FIXED_DELAY / WORKFLOW
**
任务实例停止执行请求
用户手动停止某个任务时,需要停止该任务实例
worker 需要提供符合预期的 HTTP 接口来接收 server 的请求:
- 接口地址:/worker/stopInstance
- 请求类型:POST
- 请求参数
{
"instanceId": 239140752452485440
}
任务实例运行状态查询请求
用户查看任务实例详情时,需要从 TaskTracker 查询具体的运行时信息
worker 需要提供符合预期的 HTTP 接口来接收 server 的请求:
- 接口地址:/worker/queryInstanceStatus
- 请求类型:POST
- 请求参数:
tech.powerjob.common.request.ServerQueryInstanceStatusReq
{
"instanceId": 239140752452485440
}
- 返回值
参考 Java :tech.powerjob.common.model.InstanceDetail
该接口非核心功能,可选择实现
向 server 发送请求
心跳
worker 需要定期向 server 发送心跳包,建议每 15S 发送一次请求
- 请求地址:/server/workerHeartbeat
- 请求方式:POST
- 请求参数:
tech.powerjob.common.request.WorkerHeartbeat
{
"appId":1,
"appName":"powerjob-agent-test",
"workerAddress":"192.168.124.29:27778",
"heartbeatTime":1612792419121,
"protocol":"HTTP",
"systemMetrics":{
"cpuLoad":2.4258,
"cpuProcessors":8,
"diskTotal":233.4691,
"diskUsage":0.0446,
"diskUsed":10.4179,
"jvmMaxMemory":3.5557,
"jvmMemoryUsage":0.1083,
"jvmUsedMemory":0.385,
"extra": "",
"score":11
}
}
- workerAddress:对 powerjob-server 提供 HTTP 的服务地址
- heartbeatTime:当前时间,13位时间戳
- protocol:写死 HTTP
- systemMetrics:当前系统的指标
-
- cpuLoad:load1 数据
- cpuProcessors:CPU 核心数
- diskTotal:磁盘剩余空间大小,单位 GB
- diskUsage:磁盘使用率
- diskUsed:磁盘已使用空间
- jvmMaxMemory:该进程当前最大可用内存,单位 GB(忽略 JVM)
- jvmMemoryUsage:该进程当前的内存使用率(忽略 JVM)
- jvmUsedMemory:该进程当前所使用的内存大小,单位 GB(忽略 JVM)
- score:按当前各项参数计算得到的分数,分数越高健康度排名越高,会被优先调度
任务实例状态上报
每个运行中的任务都要定时发送状态信息到 server,建议 10S 左右上报一次。
请求地址:/server/reportInstanceStatus
请求方式:POST
请求参数:tech.powerjob.common.request.TaskTrackerReportInstanceStatusReq
{
"jobId":14,
"instanceId":239146443485479232,
"reportTime":1612793022034,
"sourceAddress":"192.168.124.29:27778",
"instanceStatus":3,
}
- jobId:任务ID
- instanceId:当前任务实例ID
- reportTime:上报时间,直接取当前时间
- sourceAddress:本机地址
- instanceStatus:任务状态
返回值:根据 success 判断 server 是否接收并更新成功,若任务结束请求被 server 成功接收,则代表该任务执行完毕,需要关闭任务实例处理的单元并释放相关的资源。
{
"success": true,
"message": ""
}
在线日志
可选接口,建议实现,可在控制台直接看到日志
请求路径:/server/reportLog
请求方式:POST
请求参数:tech.powerjob.common.request.WorkerLogReportReq
{
"instanceLogContents":[
{
"instanceId":239148708413833536,
"logContent":"[DemoMRProcessor] process subTask: {"age":24,"name":"name24"}.",
"logLevel":2,
"logTime":1612793526037
},
{
"instanceId":239148708413833536,
"logContent":"[DemoMRProcessor] process subTask: {"age":25,"name":"name25"}.",
"logLevel":2,
"logTime":1612793526037
}
],
"workerAddress":"192.168.124.29:27778"
}
- instanceLogContents:数组,包含了若干条日志
-
- instanceId:任务实例ID
- logContent:日志的具体内容
- logLevel:日志级别,1 ~ 4 代表 DEBUG、INFO、WARN 和 ERROR
- logTime:日志的记录时间
- workerAddress:worker 对 server 暴露的地址
Java 参考实现:tech.powerjob.worker.log 包下所有代码