[fix] opt dockerfile & almost to release

This commit is contained in:
tjq 2020-05-21 20:31:17 +08:00
parent 46081f002a
commit 537b2e6433
21 changed files with 113 additions and 520 deletions

View File

@ -8,8 +8,8 @@ ENV APP_NAME=oh-my-scheduler-server
ENV PARAMS=""
# 将应用 jar 包拷入 docker
COPY oms-server.jar /oms-server.jar
# 暴露端口HTTP + AKKA-Server + AKKA-Client
EXPOSE 7700 10086 27777
# 暴露端口HTTP + AKKA-Server
EXPOSE 7700 10086
# 创建 docker 文件目录(盲猜这是用户目录)
RUN mkdir -p /root/oms-server
# 挂载数据卷,将文件直接输出到宿主机(注意,此处挂载的是匿名卷,即在宿主机位置随机)

View File

@ -15,6 +15,7 @@ import com.github.kfcfans.oms.server.web.request.GenerateContainerTemplateReques
import com.github.kfcfans.oms.server.web.request.SaveContainerInfoRequest;
import com.github.kfcfans.oms.server.web.response.ContainerInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
@ -94,6 +95,10 @@ public class ContainerController {
AppInfoDO appInfoDO = appInfoRepository.findById(appId).orElseThrow(() -> new IllegalArgumentException("can't find app by id:" + appId));
String targetServer = appInfoDO.getCurrentServer();
if (StringUtils.isEmpty(targetServer)) {
return ResultDTO.failed("No workers have even registered");
}
// 转发 HTTP 请求
if (!OhMyServer.getActorSystemAddress().equals(targetServer)) {
String targetIp = targetServer.split(":")[0];

View File

@ -1,4 +1,4 @@
# 没有 javac 需求,用 JRE 镜像
# agent 没有 javac 需求,用 JRE 镜像
FROM openjdk:8-jre-slim
MAINTAINER tengjiqi@gmail.com
@ -6,11 +6,9 @@ ENV APP_NAME=oh-my-scheduler-worker-agent
ENV PARAMS=""
COPY oms-agent.jar /oms-agent.jar
# 暴露端口HTTP + AKKA-Server + AKKA-Client
EXPOSE 7700 10086 27777
# 创建 docker 文件目录(盲猜这是用户目录)
RUN mkdir -p /root/oms-agent
# 暴露端口AKKA-Client
EXPOSE 27777
# 挂载数据卷,将文件直接输出到宿主机(注意,此处挂载的是匿名卷,即在宿主机位置随机)
VOLUME /root/oms
VOLUME /root
# 启动应用
ENTRYPOINT ["sh","-c","java -jar /oms-agent.jar $PARAMS"]

View File

@ -30,7 +30,7 @@ public class MainApplication implements Runnable {
private String storeStrategy = "DISK";
@Option(names = {"-s", "--server"}, description = "调度中心地址,多值英文逗号分隔,格式 IP:Port OR domain")
private String server = "127.0.0.1:7700";
private String server = "localhost:7700";
@Option(names = {"-l", "--length"}, description = "返回值最大长度")
private int length = 1024;

View File

@ -26,7 +26,7 @@
<!-- 系统所有异常日志ERROR双写 start -->
<appender name="ERROR_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/oms-server-error.log</file>
<file>${LOG_PATH}/oms-agent-error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_PATH}/oms-agent-error.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>7</MaxHistory>
@ -46,7 +46,7 @@
<!-- 系统主日志 start -->
<appender name="DEFAULT_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/oms-server-application.log</file>
<file>${LOG_PATH}/oms-agent-application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_PATH}/oms-agent-application.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>7</MaxHistory>

View File

@ -1,58 +0,0 @@
# STEP3: 任务管理 & 运行状态查看
>通过前端控制台管理调度任务,查看运行情况和结果等。
### 系统首页
> 展示了系统整体的概览和集群Worker列表。
![首页](../img/oms-console-main.png)
### 任务创建
> 创建需要被调度执行的任务,入口为**主页 -> 任务管理 -> 新建任务**。
![任务创建](../img/oms-console-jobCreator.png)
* 任务名称:名称,便于记忆与搜索,无特殊用途,请尽量简短(占用数据库字段空间)
* 任务描述:描述,无特殊作用,请尽量简短(占用数据库字段空间)
* 任务参数任务处理时能够获取到的参数即各个Processor的process方法入参`TaskContext`对象的jobParams字段进行一次处理器开发就能理解了
* 定时信息:由下拉框和输入框组成
* API -> 不需要填写任何参数(填了也不起作用)
* CRON -> 填写 CRON 表达式(可以找个[在线生成网站生成](https://www.bejson.com/othertools/cron/)
* 固定频率 -> 填写整数,单位毫秒
* 固定延迟 -> 填写整数,单位毫秒
* 执行配置由执行类型单机、广播和MapReduce、处理器类型和处理器参数组成后两项相互关联。
* 内置Java处理器 -> 填写该处理器的全限定类名eg, `com.github.kfcfans.oms.processors.demo.MapReduceProcessorDemo`
* SHELL -> 填写需要处理的脚本直接复制文件内容或脚本下载连接http://xxx
* PYTHON -> 填写完整的python脚本或下载连接http://xxx
* 运行配置
* 最大实例数:该任务同时执行的数量(任务和实例就像是类和对象的关系,任务被调度执行后被称为实例)
* 单机线程并发数该实例执行过程中每个Worker使用的线程数量MapReduce任务生效其余无论填什么都只会使用1个线程或3个线程...
* 运行时间限制:限定任务的最大运行时间,超时则视为失败,单位**毫秒**0代表不限制超时时间。
* 重试配置:
* 任务重试次数实例级别失败了整个任务实例重试会更换TaskTracker本次任务实例的Master节点代价较大大型Map/MapReduce慎用。
* 子任务重试次数Task级别每个子Task失败后单独重试会更换ProcessorTracker本次任务实际执行的Worker节点代价较小推荐使用。
* 注对于单机任务来说假如任务重试次数和子任务重试次数都配置了1且都执行失败实际执行次数会变成4次推荐任务实例重试配置为0子任务重试次数根据实际情况配置。
* 机器配置用来标明允许执行任务的机器状态避开那些摇摇欲坠的机器0代表无任何限制。
* 最低CPU核心数填写浮点数CPU可用核心数小于该值的Worker将不会执行该任务。
* 最低内存GB填写浮点数可用内存小于该值的Worker将不会执行该任务。
* 最低磁盘GB填写浮点数可用磁盘空间小于该值的Worker将不会执行该任务。
* 集群配置
* 执行机器地址指定集群中的某几台机器执行任务debug的好帮手多值英文逗号分割`192.168.1.1:27777,192.168.1.2:27777`
* 最大执行机器数量:限定调动执行的机器数量
* 报警配置:选择任务执行失败后报警通知的对象,需要事先录入。
### 任务管理
>可以方便地查看和管理系统当前录入的任务信息。
![任务管理](../img/oms-console-jobManager.png)
### 运行状态
>可以方便地查看当前运行的任务实例,点击详情即可获取详细的信息,点击日志可以查看通过`omsLogger`上报的日志,点击停止则可以强制终止该任务。
![运行状态](../img/oms-console-runningStatus.png)
### 在线日志
![在线日志](../img/oms-console-onlineLog.png)

View File

@ -1,111 +0,0 @@
# STEP4: OpenAPI
## 快速开始
>OpenAPI允许开发者通过接口来完成手工的操作让系统整体变得更加灵活启用OpenAPI需要依赖`oh-my-scheduler-client`库。
最新依赖版本请参考Maven中央仓库[推荐地址](https://search.maven.org/search?q=oh-my-scheduler-client)&[备用地址](https://mvnrepository.com/search?q=com.github.kfcfans)。
```xml
<dependency>
<groupId>com.github.kfcfans</groupId>
<artifactId>oh-my-scheduler-client</artifactId>
<version>${oms.client.latest.version}</version>
</dependency>
```
### 简单示例
```text
// 初始化 client需要server地址和应用名称作为参数
OhMyClient ohMyClient = new OhMyClient("127.0.0.1:7700", "oms-test");
// 调用相关的API
ohMyClient.stopInstance(1586855173043L)
```
## 功能列表
#### 创建/修改任务
接口签名:`ResultDTO<Long> saveJob(ClientJobInfo newJobInfo)`
入参:任务信息(详细说明见下表,也可以参考[前端任务创建各参数的正确填法](./ConsoleGuide.md)
返回值ResultDTO<Long>根据success判断操作是否成功。若操作成功data字段返回任务ID
|属性|说明|
|----|----|
|jobId|任务ID可选null代表创建任务否则填写需要修改的任务ID|
|jobName|任务名称|
|jobDescription|任务描述|
|jobParams|任务参数Processor#process方法入参`TaskContext`对象的jobParams字段|
|timeExpressionType|时间表达式类型,枚举值|
|timeExpression|时间表达式填写类型由timeExpressionType决定比如CRON需要填写CRON表达式|
|executeType|执行类型,枚举值|
|processorType|处理器类型,枚举值|
|processorInfo|处理器参数填写类型由processorType决定如Java处理器需要填写全限定类名com.github.kfcfans.oms.processors.demo.MapReduceProcessorDemo|
|maxInstanceNum|最大实例数,该任务同时执行的数量(任务和实例就像是类和对象的关系,任务被调度执行后被称为实例)|
|concurrency|单机线程并发数表示该实例执行过程中每个Worker使用的线程数量|
|instanceTimeLimit|任务实例运行时间限制0代表无任何限制超时会被打断并判定为执行失败|
|instanceRetryNum|任务实例重试次数,整个任务失败时重试,代价大,不推荐使用|
|taskRetryNum|Task重试次数每个子Task失败后单独重试代价小推荐使用|
|minCpuCores|最小可用CPU核心数CPU可用核心数小于该值的Worker将不会执行该任务0代表无任何限制|
|minMemorySpace|最小内存大小GB可用内存小于该值的Worker将不会执行该任务0代表无任何限制|
|minDiskSpace|最小磁盘大小GB可用磁盘空间小于该值的Worker将不会执行该任务0代表无任何限制|
|designatedWorkers|指定机器执行设置该参数后只有列表中的机器允许执行该任务0代表无任何限制|
|maxWorkerCount|最大执行机器数量,限定调动执行的机器数量,空代表无限制|
|notifyUserIds|接收报警的用户ID列表|
|enable|是否启用该任务,未启用的任务不会被调度|
#### 查找任务
接口签名:`ResultDTO<JobInfoDTO> fetchJob(Long jobId)`
入参任务ID
返回值根据success判断操作是否成功若请求成功则返回任务的详细信息
#### 禁用某个任务
接口签名:`ResultDTO<Void> disableJob(Long jobId)`
入参任务ID
返回值根据success判断操作是否成功
#### 启用某个任务
接口签名:`ResultDTO<Void> enableJob(Long jobId)`
入参任务ID
返回值根据success判断操作是否成功
#### 删除某个任务
接口签名:`ResultDTO<Void> deleteJob(Long jobId)`
入参任务ID
返回值根据success判断操作是否成功
#### 立即运行某个任务
接口签名:`ResultDTO<Long> runJob(Long jobId, String instanceParams)`
入参任务ID + **任务实例参数**Processor#process方法入参`TaskContext`对象的instanceParams字段
返回值根据success判断操作是否成功操作成功返回对应的任务实例ID(instanceId)
#### 停止某个任务实例
接口签名:`ResultDTO<Void> stopInstance(Long instanceId)`
入参任务实例ID
返回值根据success判断操作是否成功
#### 查询某个任务实例
接口签名:`ResultDTO<InstanceInfoDTO> fetchInstanceInfo(Long instanceId)`
入参任务实例ID
返回值根据success判断操作是否成功操作成功返回任务实例的详细信息
#### 查询某个任务实例的状态
接口签名:`ResultDTO<Integer> fetchInstanceStatus(Long instanceId)`
入参任务实例ID
返回值根据success判断操作是否成功操作成功返回任务实例的状态码对应的枚举为InstanceStatus

View File

@ -1,234 +0,0 @@
# STEP2: 处理器开发
>OhMyScheduler支持Python、Shell和Java处理器前两种处理器为脚本处理器功能简单在控制台直接配置即可本章主要介绍内置于Java项目的处理器开发。
## 宿主应用接入
#### 添加依赖
* 最新依赖版本请参考Maven中央仓库[推荐地址](https://search.maven.org/search?q=oh-my-scheduler-worker)&[备用地址](https://mvnrepository.com/search?q=com.github.kfcfans)。
```xml
<dependency>
<groupId>com.github.kfcfans</groupId>
<artifactId>oh-my-scheduler-worker</artifactId>
<version>${oms.worker.latest.version}</version>
</dependency>
```
#### 初始化客户端OhMyScheduler-Worker
> 客户端启动类为`OhMyWorker`,需要设置配置文件`OhMyConfig`并启动,以下为配置文件说明和配置示例。
OhMyConfig属性说明
|属性名称|含义|默认值|
|----|----|----|
|appName|宿主应用名称,需要提前在控制台完成注册|无,必填项,否则启动报错|
|serverAddress|服务器OhMyScheduler-Server地址列表|无,必填项,否则启动报错|
|storeStrategy|本地存储策略,枚举值磁盘/内存大型MapReduce等会产生大量Task的任务推荐使用磁盘降低内存压力否则建议使用内存加速计算|StoreStrategy.DISK磁盘|
|maxResultLength|每个Task返回结果的默认长度超长将被截断。过长可能导致网络拥塞|8096|
|enableTestMode|是否启用测试模式启用后无需Server也能顺利启动OhMyScheduler-Worker用于处理器本地的单元测试|false|
OhMyWorker启动配置Spring/SpringBoot模式
```java
@Configuration
public class OhMySchedulerConfig {
@Bean
public OhMyWorker initOMS() throws Exception {
// 服务器HTTP地址端口号为 server.port而不是 ActorSystem port
List<String> serverAddress = Lists.newArrayList("127.0.0.1:7700", "127.0.0.1:7701");
// 1. 创建配置文件
OhMyConfig config = new OhMyConfig();
config.setAppName("oms-test");
config.setServerAddress(serverAddress);
// 如果没有大型 Map/MapReduce 的需求,建议使用内存来加速计算
// 为了本地模拟多个实例,只能使用 MEMORY 启动(文件只能由一个应用占有)
config.setStoreStrategy(StoreStrategy.MEMORY);
// 2. 创建 Worker 对象,设置配置文件
OhMyWorker ohMyWorker = new OhMyWorker();
ohMyWorker.setConfig(config);
return ohMyWorker;
}
}
```
非Spring应用程序在创建`OhMyWorker`对象后手动调用`ohMyWorker.init()`方法完成初始化即可。
### 配置日志
目前OhMyScheduler-Worker并没有实现自己的LogFactory如果有需求的话请提ISSUE可以考虑实现原因如下
1. OhMyScheduler-Worker的日志基于`Slf4J`输出即采用了基于门面设计模式的日志框架宿主应用无论如何都可以搭起Slf4J与实际的日志框架这座桥梁。
2. 减轻了部分开发工作量不再需要实现自己的LogFactory虽然不怎么难就是了...)。
为此为了顺利且友好地输出日志请在日志配置文件logback.xml/log4j2.xml/...)中为`OhMyScheduler-Worker`单独进行日志配置比如logback示例
```xml
<appender name="OMS_WORKER_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/oms-worker.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_PATH}/oms-worker.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>7</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<append>true</append>
</appender>
<logger name="com.github.kfcfans.oms.worker" level="INFO" additivity="false">
<appender-ref ref="OMS_WORKER_APPENDER" />
</logger>
```
无论如何OhMyScheduler-Worker启动时都会打印Banner如下所示您可以通过Banner来判断日志配置是否成功
```text
███████ ██ ████ ████ ████████ ██ ██ ██
██░░░░░██ ░██ ░██░██ ██░██ ██ ██ ██░░░░░░ ░██ ░██ ░██
██ ░░██░██ ░██░░██ ██ ░██ ░░██ ██ ░██ █████ ░██ █████ ░██ ██ ██ ░██ █████ ██████
░██ ░██░██████ ░██ ░░███ ░██ ░░███ ░█████████ ██░░░██░██████ ██░░░██ ██████░██ ░██ ░██ ██░░░██░░██░░█
░██ ░██░██░░░██░██ ░░█ ░██ ░██ ░░░░░░░░██░██ ░░ ░██░░░██░███████ ██░░░██░██ ░██ ░██░███████ ░██ ░
░░██ ██ ░██ ░██░██ ░ ░██ ██ ░██░██ ██░██ ░██░██░░░░ ░██ ░██░██ ░██ ░██░██░░░░ ░██
░░███████ ░██ ░██░██ ░██ ██ ████████ ░░█████ ░██ ░██░░██████░░██████░░██████ ███░░██████░███
░░░░░░░ ░░ ░░ ░░ ░░ ░░ ░░░░░░░░ ░░░░░ ░░ ░░ ░░░░░░ ░░░░░░ ░░░░░░ ░░░ ░░░░░░ ░░░
```
## 处理器开发
>开发者需要根据实际需求实现`BasicProcessor`接口或继承`BroadcastProcessor``MapProcessor``MapReduceProcessor`抽象类实现处理器的开发。处理器的核心方法为`ProcessResult process(TaskContext context)`,以下为详细说明:
ProcessResult为处理返回结果包含`success``msg`两个属性。
TaskContext为处理的入参包含了本次处理的上下文信息具体属性如下
|属性名称|意义/用法|
|----|----|
|jobId|任务ID开发者一般无需关心此参数|
|instanceId|任务实例ID全局唯一开发者一般无需关心此参数|
|subInstanceId|子任务实例ID秒级任务使用开发者一般无需关心此参数|
|taskId|采用链式命名法的ID在某个任务实例内唯一开发者一般无需关心此参数|
|taskName|task名称Map/MapReduce任务的子任务的值为开发者指定否则为系统默认值开发者一般无需关心此参数|
|jobParams|任务参数,其值等同于控制台录入的**任务参数**,常用!|
|instanceParams|任务实例参数其值等同于使用OpenAPI运行任务实例时传递的参数常用|
|maxRetryTimes|Task的最大重试次数|
|currentRetryTimes|Task的当前重试次数和maxRetryTimes联合起来可以判断当前是否为该Task的最后一次运行机会|
|subTask|子TaskMap/MapReduce处理器专属开发者调用map方法时传递的子任务列表中的某一个|
|omsLogger|在线日志用法同Slf4J记录的日志可以直接通过控制台查看非常便捷和强大不过使用过程中需要注意频率可能对Server造成巨大的压力|
#### 单机处理器
>单机执行的策略下server会在所有可用worker中选取健康度最佳的机器进行执行。单机执行任务需要实现接口`com.github.kfcfans.oms.worker.core.processor.sdk.BasicProcessor`,代码示例如下:
```java
// 支持 SpringBean 的形式
@Component
public class BasicProcessorDemo implements BasicProcessor {
@Resource
private MysteryService mysteryService;
@Override
public ProcessResult process(TaskContext context) throws Exception {
// 在线日志功能,可以直接在控制台查看任务日志,非常便捷
OmsLogger omsLogger = context.getOmsLogger();
omsLogger.info("BasicProcessorDemo start to process, current JobParams is {}.", context.getJobParams());
// TaskContext为任务的上下文信息包含了在控制台录入的任务元数据常用字段为
// jobParams任务参数在控制台录入instanceParams任务实例参数通过 OpenAPI 触发的任务实例才可能存在该参数)
// 进行实际处理...
mysteryService.hasaki();
// 返回结果,该结果会被持久化到数据库,在前端页面直接查看,极为方便
return new ProcessResult(true, "result is xxx");
}
}
```
#### 广播执行处理器
>广播执行的策略下,所有机器都会被调度执行该任务。为了便于资源的准备和释放,广播处理器在`BasicProcessor`的基础上额外增加了`preProcess``postProcess`方法,分别在整个集群开始之前/结束之后**选一台机器**执行相关方法。代码示例如下:
```java
@Component
public class BroadcastProcessorDemo extends BroadcastProcessor {
@Override
public ProcessResult preProcess(TaskContext taskContext) throws Exception {
// 预执行,会在所有 worker 执行 process 方法前调用
return new ProcessResult(true, "init success");
}
@Override
public ProcessResult process(TaskContext context) throws Exception {
// 撰写整个worker集群都会执行的代码逻辑
return new ProcessResult(true, "release resource success");
}
@Override
public ProcessResult postProcess(TaskContext taskContext, List<TaskResult> taskResults) throws Exception {
// taskResults 存储了所有worker执行的结果包括preProcess
// 收尾,会在所有 worker 执行完毕 process 方法后调用,该结果将作为最终的执行结果
return new ProcessResult(true, "process success");
}
}
```
#### MapReduce处理器
>MapReduce是最复杂也是最强大的一种执行器它允许开发者完成任务的拆分将子任务派发到集群中其他Worker执行是执行大批量处理任务的不二之选实现MapReduce处理器需要继承`MapReduceProcessor`类,具体用法如下示例代码所示。
```java
@Component
public class MapReduceProcessorDemo extends MapReduceProcessor {
@Override
public ProcessResult process(TaskContext context) throws Exception {
// 判断是否为根任务
if (isRootTask()) {
// 构造子任务
List<SubTask> subTaskList = Lists.newLinkedList();
/*
* 子任务的构造由开发者自己定义
* eg. 现在需要从文件中读取100W个ID并处理数据库中这些ID对应的数据那么步骤如下
* 1. 根任务RootTask读取文件流式拉取100W个ID并按1000个一批的大小组装成子任务进行派发
* 2. 非根任务获取子任务,完成业务逻辑的处理
*/
// 调用 map 方法,派发子任务
return map(subTaskList, "DATA_PROCESS_TASK");
}
// 非子任务,可根据 subTask 的类型 或 TaskName 来判断分支
if (context.getSubTask() instanceof SubTask) {
// 执行子任务,注:子任务人可以 map 产生新的子任务,可以构建任意级的 MapReduce 处理器
return new ProcessResult(true, "PROCESS_SUB_TASK_SUCCESS");
}
return new ProcessResult(false, "UNKNOWN_BUG");
}
@Override
public ProcessResult reduce(TaskContext taskContext, List<TaskResult> taskResults) {
// 所有 Task 执行结束后reduce 将会被执行
// taskResults 保存了所有子任务的执行结果
// 用法举例,统计执行结果
AtomicLong successCnt = new AtomicLong(0);
taskResults.forEach(tr -> {
if (tr.isSuccess()) {
successCnt.incrementAndGet();
}
});
// 该结果将作为任务最终的执行结果
return new ProcessResult(true, "success task num:" + successCnt.get());
}
// 自定义的子任务
private static class SubTask {
private Long siteId;
private List<Long> idList;
}
}
```
更多示例请见:[oh-my-scheduler-worker-samples](../../oh-my-scheduler-worker-samples)

View File

@ -1,39 +0,0 @@
# STEP1: 调度中心部署 & 初始化
## 调度中心部署
#### 要求
* 运行环境JDK8+
* 编译环境Maven3+
* 关系数据库任意Spring Data JPA支持的关系型数据库MySQL/Oracle/MS SQLServer...
* mongoDB可选任意支持GridFS的mongoDB版本4.2.6测试通过,其余未经测试,仅从理论角度分析可用)
#### 流程
>注意,由于调度系统的特殊性,请务必**确保数据库和调度服务器处于同一个时区**。
1. 部署数据库:由于任务调度中心的数据持久层基于`Spring Data Jpa`实现,**开发者仅需要完成数据库的创建**即运行SQL`CREATE database if NOT EXISTS oms-product default character set utf8mb4 collate utf8mb4_unicode_ci;`
* 注1任务调度中心支持多环境部署日常、预发、线上其分别对应三个数据库oms-daily、oms-pre和oms-product。
* 注2手动建表SQL文件[oms-sql.sql](../oms-sql.sql)
* 注3部署完成后建议查看时区信息`show variables like "%time_zone%";`,务必使`time_zone`代表的时区与JDBC连接URL中`serverTimezone`字段代表的时区一致!
2. 部署调度服务器OhMyScheduler-Server需要先修改配置文件同样为了支持多环境部署采用了daily、pre和product3套配置文件之后自行编译部署运行。
* 注1OhMyScheduler-Server支持集群部署具备完全的水平扩展能力。建议部署多个实例以实现高可用&高性能。
* 注2通过启动参数`--spring.profiles.active=product`来指定使用某套配置文件默认为daily
* application-xxx.properties文件配置说明如下表所示
* |配置项|含义|可选|
|----|----|----|
|spring.datasource.core.xxx|关系型数据库连接配置|否|
|spring.mail.xxx|邮件配置|是,未配置情况下将无法使用邮件报警功能|
|spring.data.mongodb.xxx|MongoDB连接配置|是,未配置情况下将无法使用在线日志功能|
|oms.log.retention.local|本地日志保留天数,负数代表永久保留|否|
|oms.log.retention.remote|远程日志保留天数,负数代表永久保留|否|
|oms.alarm.bean.names|扩展的报警服务Bean多值逗号分割默认为邮件报警|否|
3. 部署前端页面可选每一个OhMyScheduler-Server内部自带了前端页面不过Tomcat做Web服务器的性能就呵呵了有需求追求的用户自行使用[源码](https://github.com/KFCFans/OhMyScheduler-Console)打包部署即可。
* 需要修改`main.js`中的`axios.defaults.baseURL`为实际的OhMyScheduler-Server地址
## 初始化
> 每一个需要接入OhMyScheduler的系统都需要先在控制台完成初始化即应用注册与用户录入。初始化操作在首页完成。
![Welcome Page](../img/oms-console-welcome.png)
* 每一个系统初次接入OhMyScheduler时都需要通过**应用注册**功能录入`appName`(接入应用的名称,需要保证唯一)和`appDescription`描述信息无实际用处至此应用初始化完成准备开发处理器Processor享受分布式调度和计算的便利之处吧
* 注册完成后,输入`appName`即可进入控制台。
* **用户注册**可录入用户信息,用于之后任务的报警配置。

View File

@ -8,7 +8,9 @@ bookToc: false
## 项目地址
[GitHub](https://github.com/KFCFans/OhMyScheduler) | [Gitee](https://gitee.com/KFCFans/OhMyScheduler)
GitHub[![GitHub stars](https://img.shields.io/github/stars/kfcfans/OhMyScheduler?style=social)](https://github.com/KFCFans/OhMyScheduler) [![GitHub forks](https://img.shields.io/github/forks/kfcfans/OhMyScheduler?style=social)](https://github.com/KFCFans/OhMyScheduler)
Gitee [![star](https://gitee.com/KFCFans/OhMyScheduler/badge/star.svg?theme=dark)](https://gitee.com/KFCFans/OhMyScheduler) [![fork](https://gitee.com/KFCFans/OhMyScheduler/badge/fork.svg?theme=dark)](https://gitee.com/KFCFans/OhMyScheduler)
## 产品介绍
@ -17,7 +19,7 @@ bookToc: false
* 使用简单提供前端Web界面允许开发者可视化地完成调度任务的管理增、删、改、查、任务运行状态监控和运行日志查看等功能。
* 定时策略完善支持CRON表达式、固定频率、固定延迟和API四种定时调度策略。
* 执行模式丰富支持单机、广播、Map、MapReduce四种执行模式其中Map/MapReduce处理器能使开发者寥寥数行代码便获得集群分布式计算的能力。
* 执行器支持广泛支持Spring Bean、普通Java对象、Shell、Python等处理器应用范围广比如广播执行+Shell脚本用来清理日志
* 执行器支持广泛支持Spring Bean、内置/外置Java类、Shell、Python等处理器应用范围广。
* 运维便捷支持在线日志功能执行器产生的日志可以在前端控制台页面实时显示降低debug成本极大地提高开发效率。
* 依赖精简最小仅依赖关系型数据库MySQL/Oracle/MS SQLServer...扩展依赖为MongoDB用于存储庞大的在线日志
* 高可用&高性能:调度服务器经过精心设计,一改其他调度框架基于数据库锁的策略,实现了无锁化调度。部署多个调度服务器可以同时实现高可用和性能的提升(支持无限的水平扩展)。
@ -26,7 +28,7 @@ bookToc: false
## 适用场景
* 有定时执行需求的业务场景:如每天凌晨全量同步数据、生成业务报表等。
* 有需要全部机器一同执行的业务场景:如日志清理
* 有需要全部机器一同执行的业务场景:如使用广播执行模式清理集群日志
* 有需要分布式处理的业务场景比如需要更新一大批数据单机执行耗时非常长可以使用Map/MapReduce处理器完成任务的分发调动整个集群加速计算。
## 同类产品对比

View File

@ -52,7 +52,7 @@ weight: 1
{{< /hint >}}
[Docker Hub地址](https://hub.docker.com/r/tjqq/oms-server)
[Docker Hub地址](https://hub.docker.com/r/tjqq/oms-server/tags)
部署流程:

View File

@ -106,6 +106,22 @@ public class OhMySchedulerConfig {
> agent是一个没有任何业务逻辑的执行器其实就是为worker加了一个main方法
{{< hint info >}}
**推荐直接使用Docker部署[oms-agent](https://hub.docker.com/r/tjqq/oms-agent/tags)**
{{< /hint >}}
与server一样启动参数通过环境变量`-e PARAMS`传入,全部参数请见底部。
```shell
docker run -d
-e PARAMS="--app oms-agent-test --server 192.168.1.1:7700,192.168.1.2:7700"
-p 27777:27777 --name my-oms-agent
-v ~/docker/my-oms-agent:/root tjqq/oms-agent:$version
```
***
代码编译方式启动示例:`java -jar oh-my-scheduler-worker-agent-1.2.0.jar -a my-agent`
```
@ -123,4 +139,3 @@ OhMyScheduler-Worker代理
```
Docker镜像[Docker Hub](https://hub.docker.com/r/tjqq/oms-agent)

View File

@ -1,6 +1,6 @@
---
weight: 1000
weight: 3
bookFlatSection: false
title: "更新日志"
title: "版本与升级"
---

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

75
others/script/build_docker.sh Executable file
View File

@ -0,0 +1,75 @@
#!/bin/bash
# -p允许后面跟一个字符串作为提示 -r保证读入的是原始内容不会发生任何转义
read -r -p "请输入Dockedr镜像版本:" version
echo "即将构建的 server 镜像oms-server:$version"
echo "即将构建的 agent 镜像oms-agent:$version"
read -r -p "任意键继续:"
# 一键部署脚本,请勿挪动脚本
cd `dirname $0`/../.. || exit
read -r -p "是否进行maven构建y/n:" needmvn
if [ "$needmvn" = "y" ] || [ "$needmvn" = "Y" ]; then
echo "================== 构建 jar =================="
mvn clean package -DskipTests -Pdev -U -e
echo "================== 拷贝 jar =================="
/bin/cp -rf oh-my-scheduler-server/target/*.jar oh-my-scheduler-server/oms-server.jar
/bin/cp -rf oh-my-scheduler-worker-agent/target/*.jar oh-my-scheduler-worker-agent/oms-agent.jar
ls -l oh-my-scheduler-server/oms-server.jar
ls -l oh-my-scheduler-worker-agent/oms-agent.jar
fi
echo "================== 关闭老应用 =================="
docker stop oms-server
docker stop oms-agent
docker stop oms-agent2
echo "================== 删除老容器 =================="
docker container rm oms-server
docker container rm oms-agent
docker container rm oms-agent2
read -r -p "是否重新构建镜像y/n:" rebuild
if [ "$rebuild" = "y" ] || [ "$rebuild" = "Y" ]; then
echo "================== 删除旧镜像 =================="
docker rmi -f tjqq/oms-server:$version
docker rmi -f tjqq/oms-agent:$version
echo "================== 构建 oms-server 镜像 =================="
docker build -t tjqq/oms-server:$version oh-my-scheduler-server/. || exit
echo "================== 构建 oms-agent 镜像 =================="
docker build -t tjqq/oms-agent:$version oh-my-scheduler-worker-agent/. || exit
read -r -p "是否正式发布该镜像y/n:" needrelease
if [ "$needrelease" = "y" ] || [ "$needrelease" = "Y" ]; then
read -r -p "三思请确保当前处于已发布的Master分支y/n:" needrelease
if [ "$needrelease" = "y" ] || [ "$needrelease" = "Y" ]; then
echo "================== 正在推送 server 镜像到中央仓库 =================="
docker push tjqq/oms-server:$version
echo "================== 正在推送 agent 镜像到中央仓库 =================="
docker push tjqq/oms-agent:$version
fi
fi
fi
read -r -p "是否启动 server & agenty/n:" startup
if [ "$startup" = "y" ] || [ "$startup" = "Y" ]; then
# 启动应用(端口映射、数据路径挂载)
## -d后台运行
## -p指定端口映射主机端口:容器端口
## --name指定容器名称
## -v--volume挂载目录宿主机目录docker内目录写入docker内路径的数据会被直接写到宿主机上常用于日志文件
## --net=host容器和宿主机共享网络容器直接使用宿主机IP性能最好但网络隔离较差
echo "================== 准备启动 oms-server =================="
docker run -d -e PARAMS="--spring.profiles.active=pre" -p 7700:7700 -p 10086:10086 --name oms-server -v ~/docker/oms-server:/root/oms-server tjqq/oms-server:$version
sleep 1
# tail -f -n 1000 ~/docker/oms-server/logs/oms-server-application.log
sleep 30
echo "================== 准备启动 oms-client =================="
serverIP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' oms-server)
serverAddress="$serverIP:7700"
echo "使用的Server地址$serverAddress"
docker run -d -e PARAMS="--app oms-agent-test --server $serverAddress" -p 27777:27777 --name oms-agent -v ~/docker/oms-agent:/root tjqq/oms-agent:$version
docker run -d -e PARAMS="--app oms-agent-test --server $serverAddress" -p 27778:27777 --name oms-agent2 -v ~/docker/oms-agent2:/root tjqq/oms-agent:$version
tail -f -n 100 ~/docker/oms-agent/oms/logs/oms-agent-application.log
fi

View File

@ -1,60 +0,0 @@
#!/bin/bash
# -p允许后面跟一个字符串作为提示 -r保证读入的是原始内容不会发生任何转义
read -r -p "请输入Dockedr镜像版本:" version
echo "即将构建的 server 镜像oms-server:$version"
echo "即将构建的 agent 镜像oms-agent:$version"
read -r -p "任意键继续:"
# 一键部署脚本,请勿挪动脚本
cd `dirname $0`/../.. || exit
read -r -p "是否进行maven构建y/n:" needmvn
if [ "$needmvn" = "y" ] || [ "$needmvn" = "Y" ]; then
echo "================== 构建 jar =================="
mvn clean package -DskipTests -Pdev -U -e
echo "================== 拷贝 jar =================="
/bin/cp -rf oh-my-scheduler-server/target/*.jar oh-my-scheduler-server/oms-server.jar
/bin/cp -rf oh-my-scheduler-worker-agent/target/*.jar oh-my-scheduler-worker-agent/oms-agent.jar
ls -l oh-my-scheduler-server/oms-server.jar
ls -l oh-my-scheduler-worker-agent/oms-agent.jar
fi
echo "================== 关闭老应用 =================="
docker stop oms-server
docker stop oms-agent
echo "================== 删除老容器 =================="
docker container rm oms-server
docker container rm oms-agent
echo "================== 删除旧镜像 =================="
docker rmi -f tjqq/oms-server:$version
docker rmi -f tjqq/oms-agent:$version
echo "================== 构建应用镜像 =================="
docker build -t tjqq/oms-server:$version oh-my-scheduler-server/. || exit
docker build -t tjqq/oms-agent:$version oh-my-scheduler-worker-agent/. || exit
echo "================== 准备启动应用 =================="
read -r -p "是否正式发布该镜像y/n:" needrelease
if [ "$needrelease" = "y" ] || [ "$needrelease" = "Y" ]; then
read -r -p "三思请确保当前处于已发布的Master分支y/n:" needrelease
if [ "$needrelease" = "y" ] || [ "$needrelease" = "Y" ]; then
echo "================== 正在推送 server 镜像到中央仓库 =================="
docker push tjqq/oms-server:$version
echo "================== 正在推送 agent 镜像到中央仓库 =================="
docker push tjqq/oms-agent:$version
fi
fi
read -r -p "是否启动 server & agenty/n:" startup
if [ "$startup" = "y" ] || [ "$startup" = "Y" ]; then
# 启动应用(端口映射、数据路径挂载)
## -d后台运行
## -p指定端口映射容器端口宿主机端口
## --name指定容器名称
## -v--volume挂载目录宿主机目录docker内目录写入docker内路径的数据会被直接写到宿主机上常用于日志文件
## -net=host容器和宿主机共享网络容器直接使用宿主机IP性能最好但网络隔离较差
docker run -d -e PARAMS="--spring.profiles.active=product" -p 7700:7700 -p 10086:10086 -p 27777:27777 --name oms-server -v ~/docker/oms-server:/root/oms-server tjqq/oms-server:$version
sleep 1
tail --pid=$$ -f -n 1000 ~/docker/oms-server/application.log
docker run -d -e PARAMS="--app oms-agent-test"
fi