[fix] try to fix gitee pages 404...

This commit is contained in:
tjq 2020-05-21 13:21:47 +08:00
parent 42c27cb4ed
commit cd73e81958
117 changed files with 5607 additions and 0 deletions

View File

@ -0,0 +1,52 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="theme-color" content="#FFFFFF"><meta property="og:title" content="404 Page not found" />
<meta property="og:description" content="" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://kfcfans.gitee.io/ohmyscheduler/404.html" />
<title>404 Page not found | OhMyScheduler</title>
<link rel="manifest" href="/ohmyscheduler/manifest.json">
<link rel="icon" href="/ohmyscheduler/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="/ohmyscheduler/book.min.e161f1fe2b283b6a43c29a52fde96e2387fade573e78efa6701d44c8499da76b.css" integrity="sha256-4WHx/isoO2pDwppS/eluI4f63lc&#43;eO&#43;mcB1EyEmdp2s=">
<script defer src="/ohmyscheduler/en.search.min.e2f9b2f3cf3fad006da31fc1558075ea0493c82e60c3b707d1745af9a528b273.js" integrity="sha256-4vmy888/rQBtox/BVYB16gSTyC5gw7cH0XRa&#43;aUosnM="></script>
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
<style>
.not-found {
text-align: center;
}
.not-found h1 {
margin: .25em 0 0 0;
opacity: .25;
font-size: 40vmin;
}
</style>
</head>
<body>
<main class="flex justify-center not-found">
<div>
<h1>404</h1>
<h2>Page Not Found</h2>
<h3>
<a href="/ohmyscheduler/">OhMyScheduler</a>
</h3>
</div>
</main>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,346 @@
<!DOCTYPE html>
<html lang="en" dir=>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="theme-color" content="#FFFFFF"><meta property="og:title" content="Categories" />
<meta property="og:description" content="" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://kfcfans.gitee.io/ohmyscheduler/categories/" />
<title>Categories | OhMyScheduler</title>
<link rel="manifest" href="/ohmyscheduler/manifest.json">
<link rel="icon" href="/ohmyscheduler/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="/ohmyscheduler/book.min.e161f1fe2b283b6a43c29a52fde96e2387fade573e78efa6701d44c8499da76b.css" integrity="sha256-4WHx/isoO2pDwppS/eluI4f63lc&#43;eO&#43;mcB1EyEmdp2s=">
<script defer src="/ohmyscheduler/en.search.min.e2f9b2f3cf3fad006da31fc1558075ea0493c82e60c3b707d1745af9a528b273.js" integrity="sha256-4vmy888/rQBtox/BVYB16gSTyC5gw7cH0XRa&#43;aUosnM="></script>
<link rel="alternate" type="application/rss+xml" href="https://kfcfans.gitee.io/ohmyscheduler/categories/index.xml" title="OhMyScheduler" />
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
</head>
<body dir=>
<input type="checkbox" class="hidden" id="menu-control" />
<main class="container flex">
<aside class="book-menu">
<nav>
<h2 class="book-brand">
<a href="/ohmyscheduler"><span>OhMyScheduler</span>
</a>
</h2>
<div class="book-search">
<input type="text" id="book-search-input" placeholder="Search" aria-label="Search" maxlength="64" data-hotkeys="s/" />
<div class="book-search-spinner hidden"></div>
<ul id="book-search-results"></ul>
</div>
<ul>
<li>
<span>快速开始</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/startup/1-server-startup/" class="">调度中心Server部署</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/2-worker-startup/" class="">执行器Worker初始化</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/3-processor-develop/" class="">处理器开发</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/4-console-guide/" class="">任务管理与在线运维</a>
</li>
</ul>
</li>
<li>
<span>高级特性</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/super/container/" class="">容器</a>
</li>
<li>
<a href="/ohmyscheduler/docs/super/openapi/" class="">OpenAPI</a>
</li>
</ul>
</li>
<li>
<span>更新日志</span>
<ul>
</ul>
</li>
</ul>
</nav>
<script>(function(){var menu=document.querySelector("aside.book-menu nav");addEventListener("beforeunload",function(event){localStorage.setItem("menu.scrollTop",menu.scrollTop);});menu.scrollTop=localStorage.getItem("menu.scrollTop");})();</script>
</aside>
<div class="book-page">
<header class="book-header">
<div class="flex align-center justify-between">
<label for="menu-control">
<img src="/ohmyscheduler/svg/menu.svg" class="book-icon" alt="Menu" />
</label>
<strong>Categories</strong>
<label for="toc-control">
<img src="/ohmyscheduler/svg/toc.svg" class="book-icon" alt="Table of Contents" />
</label>
</div>
<input type="checkbox" class="hidden" id="toc-control" />
<aside class="hidden clearfix">
<nav>
<ul>
<li class="book-section-flat">
<strong>Categories</strong>
<ul>
</ul>
</li>
<li class="book-section-flat">
<strong>Tags</strong>
<ul>
</ul>
</li>
</ul>
</nav>
</aside>
</header>
<article class="markdown">
<h1>Categories</h1>
</article>
<footer class="book-footer">
<div class="flex flex-wrap justify-between">
</div>
</footer>
<label for="menu-control" class="hidden book-menu-overlay"></label>
</div>
<aside class="book-toc">
<nav>
<ul>
<li class="book-section-flat">
<strong>Categories</strong>
<ul>
</ul>
</li>
<li class="book-section-flat">
<strong>Tags</strong>
<ul>
</ul>
</li>
</ul>
</nav>
</aside>
</main>
</body>
</html>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Categories on OhMyScheduler</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/categories/</link>
<description>Recent content in Categories on OhMyScheduler</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<atom:link href="https://kfcfans.gitee.io/ohmyscheduler/categories/index.xml" rel="self" type="application/rss+xml" />
</channel>
</rss>

View File

@ -0,0 +1,298 @@
<!DOCTYPE html>
<html lang="en" dir=>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="theme-color" content="#FFFFFF"><meta property="og:title" content="Docs" />
<meta property="og:description" content="" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://kfcfans.gitee.io/ohmyscheduler/docs/" />
<title>Docs | OhMyScheduler</title>
<link rel="manifest" href="/ohmyscheduler/manifest.json">
<link rel="icon" href="/ohmyscheduler/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="/ohmyscheduler/book.min.e161f1fe2b283b6a43c29a52fde96e2387fade573e78efa6701d44c8499da76b.css" integrity="sha256-4WHx/isoO2pDwppS/eluI4f63lc&#43;eO&#43;mcB1EyEmdp2s=">
<script defer src="/ohmyscheduler/en.search.min.e2f9b2f3cf3fad006da31fc1558075ea0493c82e60c3b707d1745af9a528b273.js" integrity="sha256-4vmy888/rQBtox/BVYB16gSTyC5gw7cH0XRa&#43;aUosnM="></script>
<link rel="alternate" type="application/rss+xml" href="https://kfcfans.gitee.io/ohmyscheduler/docs/index.xml" title="OhMyScheduler" />
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
</head>
<body dir=>
<input type="checkbox" class="hidden" id="menu-control" />
<main class="container flex">
<aside class="book-menu">
<nav>
<h2 class="book-brand">
<a href="/ohmyscheduler"><span>OhMyScheduler</span>
</a>
</h2>
<div class="book-search">
<input type="text" id="book-search-input" placeholder="Search" aria-label="Search" maxlength="64" data-hotkeys="s/" />
<div class="book-search-spinner hidden"></div>
<ul id="book-search-results"></ul>
</div>
<ul>
<li>
<span>快速开始</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/startup/1-server-startup/" class="">调度中心Server部署</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/2-worker-startup/" class="">执行器Worker初始化</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/3-processor-develop/" class="">处理器开发</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/4-console-guide/" class="">任务管理与在线运维</a>
</li>
</ul>
</li>
<li>
<span>高级特性</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/super/container/" class="">容器</a>
</li>
<li>
<a href="/ohmyscheduler/docs/super/openapi/" class="">OpenAPI</a>
</li>
</ul>
</li>
<li>
<span>更新日志</span>
<ul>
</ul>
</li>
</ul>
</nav>
<script>(function(){var menu=document.querySelector("aside.book-menu nav");addEventListener("beforeunload",function(event){localStorage.setItem("menu.scrollTop",menu.scrollTop);});menu.scrollTop=localStorage.getItem("menu.scrollTop");})();</script>
</aside>
<div class="book-page">
<header class="book-header">
<div class="flex align-center justify-between">
<label for="menu-control">
<img src="/ohmyscheduler/svg/menu.svg" class="book-icon" alt="Menu" />
</label>
<strong>Docs</strong>
<label for="toc-control">
<img src="/ohmyscheduler/svg/toc.svg" class="book-icon" alt="Table of Contents" />
</label>
</div>
<input type="checkbox" class="hidden" id="toc-control" />
<aside class="hidden clearfix">
</aside>
</header>
<article class="markdown"></article>
<footer class="book-footer">
<div class="flex flex-wrap justify-between">
</div>
</footer>
<label for="menu-control" class="hidden book-menu-overlay"></label>
</div>
<aside class="book-toc">
</aside>
</main>
</body>
</html>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Docs on OhMyScheduler</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/docs/</link>
<description>Recent content in Docs on OhMyScheduler</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<atom:link href="https://kfcfans.gitee.io/ohmyscheduler/docs/index.xml" rel="self" type="application/rss+xml" />
</channel>
</rss>

View File

@ -0,0 +1,470 @@
<!DOCTYPE html>
<html lang="en" dir=>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="环境要求 Open JDK 8&#43;
Apache Maven 3&#43;
任意 Spring Data Jpa 支持的关系型数据库MySQL/Oracle/MS SQLServer&hellip;
MongoDB可选任意支持GridFS的mongoDB版本4.2.6测试通过,其余未经测试,仅从理论角度分析可用),缺失该组件的情况下将无法使用在线日志、容器部署等扩展功能
初始化关系数据库 调度服务器oh-my-scheduler-server的持久化层基于Spring Boot Jpa实现对于能够直连数据库的应用开发者仅需完成数据库的创建即运行SQLCREATE database if NOT EXISTS oms-product default character set utf8mb4 collate utf8mb4_unicode_ci;`
OhMyScheduler支持环境隔离提供日常daily、预发pre和线上product三套环境请根据使用的环境分别部署对应的数据库oms-daily、oms-pre和oms-product。 调度服务器属于时间敏感应用强烈建议检查当前数据库所使用的时区信息show variables like &quot;%time_zone%&quot;;务必确保time_zone代表的时区与JDBC URL中serverTimezone字段代表的时区一致 手动建表表SQL文件下载地址 部署调度服务器—源码编译 调度服务器oh-my-scheduler-server支持任意的水平扩展即多实例集群部署仅需要在同一个局域网内启动新的服务器实例性能强劲无上限
调度服务器oh-my-scheduler-server为了支持环境隔离分别采用了日常application-daily.properties、预发application-pre.properties和线上application-product.properties三套配置文件请根据实际需求进行修改以下为配置文件详解。
配置项 含义 可选 server.port SpringBoot配置HTTP端口号默认7700 否 oms.">
<meta name="theme-color" content="#FFFFFF"><meta property="og:title" content="调度中心Server部署" />
<meta property="og:description" content="环境要求 Open JDK 8&#43;
Apache Maven 3&#43;
任意 Spring Data Jpa 支持的关系型数据库MySQL/Oracle/MS SQLServer&hellip;
MongoDB可选任意支持GridFS的mongoDB版本4.2.6测试通过,其余未经测试,仅从理论角度分析可用),缺失该组件的情况下将无法使用在线日志、容器部署等扩展功能
初始化关系数据库 调度服务器oh-my-scheduler-server的持久化层基于Spring Boot Jpa实现对于能够直连数据库的应用开发者仅需完成数据库的创建即运行SQLCREATE database if NOT EXISTS oms-product default character set utf8mb4 collate utf8mb4_unicode_ci;`
OhMyScheduler支持环境隔离提供日常daily、预发pre和线上product三套环境请根据使用的环境分别部署对应的数据库oms-daily、oms-pre和oms-product。 调度服务器属于时间敏感应用强烈建议检查当前数据库所使用的时区信息show variables like &quot;%time_zone%&quot;;务必确保time_zone代表的时区与JDBC URL中serverTimezone字段代表的时区一致 手动建表表SQL文件下载地址 部署调度服务器—源码编译 调度服务器oh-my-scheduler-server支持任意的水平扩展即多实例集群部署仅需要在同一个局域网内启动新的服务器实例性能强劲无上限
调度服务器oh-my-scheduler-server为了支持环境隔离分别采用了日常application-daily.properties、预发application-pre.properties和线上application-product.properties三套配置文件请根据实际需求进行修改以下为配置文件详解。
配置项 含义 可选 server.port SpringBoot配置HTTP端口号默认7700 否 oms." />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://kfcfans.gitee.io/ohmyscheduler/docs/startup/1-server-startup/" />
<title>调度中心Server部署 | OhMyScheduler</title>
<link rel="manifest" href="/ohmyscheduler/manifest.json">
<link rel="icon" href="/ohmyscheduler/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="/ohmyscheduler/book.min.e161f1fe2b283b6a43c29a52fde96e2387fade573e78efa6701d44c8499da76b.css" integrity="sha256-4WHx/isoO2pDwppS/eluI4f63lc&#43;eO&#43;mcB1EyEmdp2s=">
<script defer src="/ohmyscheduler/en.search.min.e2f9b2f3cf3fad006da31fc1558075ea0493c82e60c3b707d1745af9a528b273.js" integrity="sha256-4vmy888/rQBtox/BVYB16gSTyC5gw7cH0XRa&#43;aUosnM="></script>
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
</head>
<body dir=>
<input type="checkbox" class="hidden" id="menu-control" />
<main class="container flex">
<aside class="book-menu">
<nav>
<h2 class="book-brand">
<a href="/ohmyscheduler"><span>OhMyScheduler</span>
</a>
</h2>
<div class="book-search">
<input type="text" id="book-search-input" placeholder="Search" aria-label="Search" maxlength="64" data-hotkeys="s/" />
<div class="book-search-spinner hidden"></div>
<ul id="book-search-results"></ul>
</div>
<ul>
<li>
<span>快速开始</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/startup/1-server-startup/" class="active">调度中心Server部署</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/2-worker-startup/" class="">执行器Worker初始化</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/3-processor-develop/" class="">处理器开发</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/4-console-guide/" class="">任务管理与在线运维</a>
</li>
</ul>
</li>
<li>
<span>高级特性</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/super/container/" class="">容器</a>
</li>
<li>
<a href="/ohmyscheduler/docs/super/openapi/" class="">OpenAPI</a>
</li>
</ul>
</li>
<li>
<span>更新日志</span>
<ul>
</ul>
</li>
</ul>
</nav>
<script>(function(){var menu=document.querySelector("aside.book-menu nav");addEventListener("beforeunload",function(event){localStorage.setItem("menu.scrollTop",menu.scrollTop);});menu.scrollTop=localStorage.getItem("menu.scrollTop");})();</script>
</aside>
<div class="book-page">
<header class="book-header">
<div class="flex align-center justify-between">
<label for="menu-control">
<img src="/ohmyscheduler/svg/menu.svg" class="book-icon" alt="Menu" />
</label>
<strong>调度中心Server部署</strong>
<label for="toc-control">
<img src="/ohmyscheduler/svg/toc.svg" class="book-icon" alt="Table of Contents" />
</label>
</div>
<input type="checkbox" class="hidden" id="toc-control" />
<aside class="hidden clearfix">
<nav id="TableOfContents">
<ul>
<li><a href="#环境要求">环境要求</a></li>
<li><a href="#初始化关系数据库">初始化关系数据库</a></li>
<li><a href="#部署调度服务器源码编译">部署调度服务器—源码编译</a></li>
<li><a href="#部署调度服务器docker">部署调度服务器—Docker</a></li>
<li><a href="#单独部署前端页面可选">单独部署前端页面(可选)</a></li>
<li><a href="#初始化应用分组">初始化应用分组</a></li>
</ul>
</nav>
</aside>
</header>
<article class="markdown"><h2 id="环境要求">环境要求</h2>
<ul>
<li>
<p>Open JDK 8+</p>
</li>
<li>
<p>Apache Maven 3+</p>
</li>
<li>
<p>任意 Spring Data Jpa 支持的关系型数据库MySQL/Oracle/MS SQLServer&hellip;</p>
</li>
<li>
<p>MongoDB可选任意支持GridFS的mongoDB版本4.2.6测试通过,其余未经测试,仅从理论角度分析可用),缺失该组件的情况下将无法使用在线日志、容器部署等扩展功能</p>
</li>
</ul>
<h2 id="初始化关系数据库">初始化关系数据库</h2>
<blockquote>
<p>调度服务器oh-my-scheduler-server的持久化层基于<code>Spring Boot Jpa</code>实现,对于能够直连数据库的应用,开发者<strong>仅需完成数据库的创建</strong>即运行SQLCREATE database if NOT EXISTS oms-product default character set utf8mb4 collate utf8mb4_unicode_ci;`</p>
</blockquote>
<ul>
<li>OhMyScheduler支持<strong>环境隔离</strong>提供日常daily、预发pre和线上product三套环境请根据使用的环境分别部署对应的数据库<code>oms-daily</code><code>oms-pre</code><code>oms-product</code></li>
<li>调度服务器属于<strong>时间敏感</strong>应用,强烈建议检查当前数据库所使用的时区信息(<code>show variables like &quot;%time_zone%&quot;;</code>),务必确保<code>time_zone</code>代表的时区与JDBC URL中<code>serverTimezone</code>字段代表的时区一致!</li>
<li>手动建表表SQL文件<a href="https://github.com/KFCFans/OhMyScheduler/blob/master/others/oms-sql.sql">下载地址</a></li>
</ul>
<h2 id="部署调度服务器源码编译">部署调度服务器—源码编译</h2>
<blockquote>
<p>调度服务器oh-my-scheduler-server支持任意的水平扩展即多实例集群部署仅需要在同一个局域网内启动新的服务器实例性能强劲无上限</p>
</blockquote>
<p>调度服务器oh-my-scheduler-server为了支持环境隔离分别采用了日常<code>application-daily.properties</code>)、预发(<code>application-pre.properties</code>)和线上(<code>application-product.properties</code>)三套配置文件,请根据实际需求进行修改,以下为配置文件详解。</p>
<table>
<thead>
<tr>
<th>配置项</th>
<th>含义</th>
<th>可选</th>
</tr>
</thead>
<tbody>
<tr>
<td>server.port</td>
<td>SpringBoot配置HTTP端口号默认7700</td>
<td></td>
</tr>
<tr>
<td>oms.akka.port</td>
<td>OhMyScheduler配置Akka端口号默认10086</td>
<td></td>
</tr>
<tr>
<td>oms.alarm.bean.names</td>
<td>OhMyScheduler报警服务Bean名称多值逗号分隔</td>
<td></td>
</tr>
<tr>
<td>spring.datasource.core.xxx</td>
<td>关系型数据库连接配置</td>
<td></td>
</tr>
<tr>
<td>spring.mail.xxx</td>
<td>邮件配置</td>
<td>是,未配置情况下将无法使用邮件报警功能</td>
</tr>
<tr>
<td>spring.data.mongodb.xxx</td>
<td>MongoDB连接配置</td>
<td>是,未配置情况下将无法使用在线日志功能</td>
</tr>
<tr>
<td>oms.log.retention.local</td>
<td>本地日志保留天数,负数代表永久保留</td>
<td></td>
</tr>
<tr>
<td>oms.log.retention.remote</td>
<td>远程日志保留天数,负数代表永久保留</td>
<td></td>
</tr>
<tr>
<td>oms.container.retention.local</td>
<td>扩展的报警服务Bean多值逗号分割默认为邮件报警</td>
<td></td>
</tr>
<tr>
<td>oms.container.retention.remote</td>
<td>远程容器保留天数,负数代表永久保留</td>
<td></td>
</tr>
</tbody>
</table>
<p>完成配置文件修改后,即可正式开始部署:</p>
<ul>
<li>打包:运行<code>mvn clean package -U -Pdev -DskipTests</code>构建调度中心Jar文件。</li>
<li>运行:运行<code>java -jar oms-server.jar --spring.profiles.active=product</code>,指定生效的配置文件。</li>
<li>验证:访问<code>http://ip:port</code>查看是否出现OhMyScheduler的欢迎页面。</li>
</ul>
<h2 id="部署调度服务器docker">部署调度服务器—Docker</h2>
<blockquote class="book-hint warning">
<strong>建议自己根据项目中的Dockerfile稍作修改制作自己的Docker镜像而不是直接使用官方镜像</strong>原因在于容器功能需要用到Git和Maven来编译代码库而公司内部往往都会搭建自己的私有仓库所以Git容器功能没办法正常运行<strong>官方镜像中的调度服务器不支持Git容器的部署</strong>)。
</blockquote>
<p><a href="https://hub.docker.com/r/tjqq/oms-server">Docker Hub地址</a></p>
<p>部署流程:</p>
<ol>
<li>下载镜像:<code>docker pull tjqq/oms-server</code></li>
<li>创建容器并运行所有SpringBoot的启动参数都可通过<code>-e Params=&quot;&quot;</code>传入)</li>
</ol>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-shell" data-lang="shell">docker run -d
-e PARAMS<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;--spring.profiles.active=product&#34;</span>
-p 7700:7700 -p 10086:10086 -p 27777:27777
--name oms-server
-v ~/docker/oms-server:/root/oms-server tjqq/oms-server:$version
</code></pre></div><h2 id="单独部署前端页面可选">单独部署前端页面(可选)</h2>
<blockquote>
<p>每一个oh-my-scheduler-server都自带了前端页面不过<del><del>Tomcat</del></del>为了完善的WebSocket支持现已切换到Undertow做Web服务器的性能就<del><del>呵呵了</del></del>(看评测好像还行,不过有追求的用户还是建议单独使用源码部署)~</p>
</blockquote>
<ol>
<li>源码克隆:<a href="https://github.com/KFCFans/OhMyScheduler-Console">OhMyScheduler-Console</a></li>
<li>替换地址:修改<code>main.js</code>中的<code>axios.defaults.baseURL</code>为服务器地址</li>
<li>npm run build -&gt; nginx config</li>
</ol>
<hr>
<p><strong>特别鸣谢</strong>:感谢<a href="https://github.com/fengnan0929">某知名上市电商公司前端开发者</a>对本项目的大力支持!</p>
<h2 id="初始化应用分组">初始化应用分组</h2>
<blockquote>
<p>每一个业务系统初次接入OhMyScheduler时都需要<strong>先完成应用注册</strong></p>
</blockquote>
<p><img src="/oms-console-welcome.png" alt="WelcomePage" /></p>
<ul>
<li>应用注册,用于进行业务分组:
<ul>
<li>应用名称:关键参数,一般填入接入的业务应用名称即可,需要保证唯一。<strong>同一个应用名称的所有worker视为一个集群被调度中心调度。</strong></li>
<li>应用描述:可选参数,便于记忆,无实际用处。</li>
</ul>
</li>
<li>用户注册,用于收集报警信息,用户注册录入个人信息后,即可通过报警配置进行通知。</li>
</ul>
</article>
<footer class="book-footer">
<div class="flex flex-wrap justify-between">
</div>
</footer>
<div class="book-comments">
</div>
<label for="menu-control" class="hidden book-menu-overlay"></label>
</div>
<aside class="book-toc">
<nav id="TableOfContents">
<ul>
<li><a href="#环境要求">环境要求</a></li>
<li><a href="#初始化关系数据库">初始化关系数据库</a></li>
<li><a href="#部署调度服务器源码编译">部署调度服务器—源码编译</a></li>
<li><a href="#部署调度服务器docker">部署调度服务器—Docker</a></li>
<li><a href="#单独部署前端页面可选">单独部署前端页面(可选)</a></li>
<li><a href="#初始化应用分组">初始化应用分组</a></li>
</ul>
</nav>
</aside>
</main>
</body>
</html>

View File

@ -0,0 +1,447 @@
<!DOCTYPE html>
<html lang="en" dir=>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="基于宿主应用的执行器初始化 宿主应用即原有的业务应用假如需要调度执行的任务与当前业务有较为紧密的联系建议采取该方式
首先添加相关的jar包依赖最新依赖版本请参考maven中央仓库推荐地址&amp;备用地址
&lt;dependency&gt; &lt;groupId&gt;com.github.kfcfans&lt;/groupId&gt; &lt;artifactId&gt;oh-my-scheduler-worker&lt;/artifactId&gt; &lt;version&gt;1.2.0&lt;/version&gt; &lt;/dependency&gt; 其次填写执行器客户端配置文件OhMyConfig各参数说明如下表所示
属性名称 含义 默认值 appName 宿主应用名称,需要提前在控制台完成注册 无,必填项,否则启动报错 port Worker工作端口 27777 serverAddress 调度中心oh-my-scheduler-server地址列表 无,必填项,否则启动报错 storeStrategy 本地存储策略,枚举值磁盘/内存大型MapReduce等会产生大量Task的任务推荐使用磁盘降低内存压力否则建议使用内存加速计算 StoreStrategy.DISK磁盘 maxResultLength 每个Task返回结果的默认长度超长将被截断。过长可能导致网络拥塞 8096 enableTestMode 是否启用测试模式启用后无需Server也能顺利启动OhMyScheduler-Worker用于处理器本地的单元测试 false 最后,初始化客户端,完成执行器的启动,代码示例如下:
@Configuration public class OhMySchedulerConfig { @Bean public OhMyWorker initOMS() throws Exception { // 服务器HTTP地址端口号为 server.port而不是 ActorSystem port List&lt;String&gt; serverAddress = Lists.">
<meta name="theme-color" content="#FFFFFF"><meta property="og:title" content="执行器Worker初始化" />
<meta property="og:description" content="基于宿主应用的执行器初始化 宿主应用即原有的业务应用假如需要调度执行的任务与当前业务有较为紧密的联系建议采取该方式
首先添加相关的jar包依赖最新依赖版本请参考maven中央仓库推荐地址&amp;备用地址
&lt;dependency&gt; &lt;groupId&gt;com.github.kfcfans&lt;/groupId&gt; &lt;artifactId&gt;oh-my-scheduler-worker&lt;/artifactId&gt; &lt;version&gt;1.2.0&lt;/version&gt; &lt;/dependency&gt; 其次填写执行器客户端配置文件OhMyConfig各参数说明如下表所示
属性名称 含义 默认值 appName 宿主应用名称,需要提前在控制台完成注册 无,必填项,否则启动报错 port Worker工作端口 27777 serverAddress 调度中心oh-my-scheduler-server地址列表 无,必填项,否则启动报错 storeStrategy 本地存储策略,枚举值磁盘/内存大型MapReduce等会产生大量Task的任务推荐使用磁盘降低内存压力否则建议使用内存加速计算 StoreStrategy.DISK磁盘 maxResultLength 每个Task返回结果的默认长度超长将被截断。过长可能导致网络拥塞 8096 enableTestMode 是否启用测试模式启用后无需Server也能顺利启动OhMyScheduler-Worker用于处理器本地的单元测试 false 最后,初始化客户端,完成执行器的启动,代码示例如下:
@Configuration public class OhMySchedulerConfig { @Bean public OhMyWorker initOMS() throws Exception { // 服务器HTTP地址端口号为 server.port而不是 ActorSystem port List&lt;String&gt; serverAddress = Lists." />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://kfcfans.gitee.io/ohmyscheduler/docs/startup/2-worker-startup/" />
<title>执行器Worker初始化 | OhMyScheduler</title>
<link rel="manifest" href="/ohmyscheduler/manifest.json">
<link rel="icon" href="/ohmyscheduler/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="/ohmyscheduler/book.min.e161f1fe2b283b6a43c29a52fde96e2387fade573e78efa6701d44c8499da76b.css" integrity="sha256-4WHx/isoO2pDwppS/eluI4f63lc&#43;eO&#43;mcB1EyEmdp2s=">
<script defer src="/ohmyscheduler/en.search.min.e2f9b2f3cf3fad006da31fc1558075ea0493c82e60c3b707d1745af9a528b273.js" integrity="sha256-4vmy888/rQBtox/BVYB16gSTyC5gw7cH0XRa&#43;aUosnM="></script>
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
</head>
<body dir=>
<input type="checkbox" class="hidden" id="menu-control" />
<main class="container flex">
<aside class="book-menu">
<nav>
<h2 class="book-brand">
<a href="/ohmyscheduler"><span>OhMyScheduler</span>
</a>
</h2>
<div class="book-search">
<input type="text" id="book-search-input" placeholder="Search" aria-label="Search" maxlength="64" data-hotkeys="s/" />
<div class="book-search-spinner hidden"></div>
<ul id="book-search-results"></ul>
</div>
<ul>
<li>
<span>快速开始</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/startup/1-server-startup/" class="">调度中心Server部署</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/2-worker-startup/" class="active">执行器Worker初始化</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/3-processor-develop/" class="">处理器开发</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/4-console-guide/" class="">任务管理与在线运维</a>
</li>
</ul>
</li>
<li>
<span>高级特性</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/super/container/" class="">容器</a>
</li>
<li>
<a href="/ohmyscheduler/docs/super/openapi/" class="">OpenAPI</a>
</li>
</ul>
</li>
<li>
<span>更新日志</span>
<ul>
</ul>
</li>
</ul>
</nav>
<script>(function(){var menu=document.querySelector("aside.book-menu nav");addEventListener("beforeunload",function(event){localStorage.setItem("menu.scrollTop",menu.scrollTop);});menu.scrollTop=localStorage.getItem("menu.scrollTop");})();</script>
</aside>
<div class="book-page">
<header class="book-header">
<div class="flex align-center justify-between">
<label for="menu-control">
<img src="/ohmyscheduler/svg/menu.svg" class="book-icon" alt="Menu" />
</label>
<strong>执行器Worker初始化</strong>
<label for="toc-control">
<img src="/ohmyscheduler/svg/toc.svg" class="book-icon" alt="Table of Contents" />
</label>
</div>
<input type="checkbox" class="hidden" id="toc-control" />
<aside class="hidden clearfix">
<nav id="TableOfContents">
<ul>
<li><a href="#基于宿主应用的执行器初始化">基于宿主应用的执行器初始化</a></li>
<li><a href="#基于agent的执行器初始化">基于agent的执行器初始化</a></li>
</ul>
</nav>
</aside>
</header>
<article class="markdown"><h2 id="基于宿主应用的执行器初始化">基于宿主应用的执行器初始化</h2>
<blockquote>
<p>宿主应用即原有的业务应用,假如需要调度执行的任务与当前业务有较为紧密的联系,建议采取该方式。</p>
</blockquote>
<p>首先添加相关的jar包依赖最新依赖版本请参考maven中央仓库<a href="https://search.maven.org/search?q=oh-my-scheduler-worker">推荐地址</a>&amp;<a href="https://mvnrepository.com/search?q=com.github.kfcfans">备用地址</a></p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-xml" data-lang="xml"><span style="color:#f92672">&lt;dependency&gt;</span>
<span style="color:#f92672">&lt;groupId&gt;</span>com.github.kfcfans<span style="color:#f92672">&lt;/groupId&gt;</span>
<span style="color:#f92672">&lt;artifactId&gt;</span>oh-my-scheduler-worker<span style="color:#f92672">&lt;/artifactId&gt;</span>
<span style="color:#f92672">&lt;version&gt;</span>1.2.0<span style="color:#f92672">&lt;/version&gt;</span>
<span style="color:#f92672">&lt;/dependency&gt;</span>
</code></pre></div><p>其次,填写执行器客户端配置文件<code>OhMyConfig</code>,各参数说明如下表所示:</p>
<table>
<thead>
<tr>
<th>属性名称</th>
<th>含义</th>
<th>默认值</th>
</tr>
</thead>
<tbody>
<tr>
<td>appName</td>
<td>宿主应用名称,需要提前在控制台完成注册</td>
<td>无,必填项,否则启动报错</td>
</tr>
<tr>
<td>port</td>
<td>Worker工作端口</td>
<td>27777</td>
</tr>
<tr>
<td>serverAddress</td>
<td>调度中心oh-my-scheduler-server地址列表</td>
<td>无,必填项,否则启动报错</td>
</tr>
<tr>
<td>storeStrategy</td>
<td>本地存储策略,枚举值磁盘/内存大型MapReduce等会产生大量Task的任务推荐使用磁盘降低内存压力否则建议使用内存加速计算</td>
<td>StoreStrategy.DISK磁盘</td>
</tr>
<tr>
<td>maxResultLength</td>
<td>每个Task返回结果的默认长度超长将被截断。过长可能导致网络拥塞</td>
<td>8096</td>
</tr>
<tr>
<td>enableTestMode</td>
<td>是否启用测试模式启用后无需Server也能顺利启动OhMyScheduler-Worker用于处理器本地的单元测试</td>
<td>false</td>
</tr>
</tbody>
</table>
<p>最后,初始化客户端,完成执行器的启动,代码示例如下:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#a6e22e">@Configuration</span>
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">OhMySchedulerConfig</span> <span style="color:#f92672">{</span>
<span style="color:#a6e22e">@Bean</span>
<span style="color:#66d9ef">public</span> OhMyWorker <span style="color:#a6e22e">initOMS</span><span style="color:#f92672">()</span> <span style="color:#66d9ef">throws</span> Exception <span style="color:#f92672">{</span>
<span style="color:#75715e">// 服务器HTTP地址端口号为 server.port而不是 ActorSystem port
</span><span style="color:#75715e"></span> List<span style="color:#f92672">&lt;</span>String<span style="color:#f92672">&gt;</span> serverAddress <span style="color:#f92672">=</span> Lists<span style="color:#f92672">.</span><span style="color:#a6e22e">newArrayList</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;127.0.0.1:7700&#34;</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;127.0.0.1:7701&#34;</span><span style="color:#f92672">);</span>
<span style="color:#75715e">// 1. 创建配置文件
</span><span style="color:#75715e"></span> OhMyConfig config <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> OhMyConfig<span style="color:#f92672">();</span>
config<span style="color:#f92672">.</span><span style="color:#a6e22e">setPort</span><span style="color:#f92672">(</span>27777<span style="color:#f92672">);</span>
config<span style="color:#f92672">.</span><span style="color:#a6e22e">setAppName</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;oms-test&#34;</span><span style="color:#f92672">);</span>
config<span style="color:#f92672">.</span><span style="color:#a6e22e">setServerAddress</span><span style="color:#f92672">(</span>serverAddress<span style="color:#f92672">);</span>
<span style="color:#75715e">// 如果没有大型 Map/MapReduce 的需求,建议使用内存来加速计算
</span><span style="color:#75715e"></span> <span style="color:#75715e">// 为了本地模拟多个实例,只能使用 MEMORY 启动(文件只能由一个应用占有)
</span><span style="color:#75715e"></span> config<span style="color:#f92672">.</span><span style="color:#a6e22e">setStoreStrategy</span><span style="color:#f92672">(</span>StoreStrategy<span style="color:#f92672">.</span><span style="color:#a6e22e">MEMORY</span><span style="color:#f92672">);</span>
<span style="color:#75715e">// 2. 创建 Worker 对象,设置配置文件
</span><span style="color:#75715e"></span> OhMyWorker ohMyWorker <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> OhMyWorker<span style="color:#f92672">();</span>
ohMyWorker<span style="color:#f92672">.</span><span style="color:#a6e22e">setConfig</span><span style="color:#f92672">(</span>config<span style="color:#f92672">);</span>
<span style="color:#66d9ef">return</span> ohMyWorker<span style="color:#f92672">;</span>
<span style="color:#f92672">}</span>
<span style="color:#f92672">}</span>
</code></pre></div><p>非Spring应用程序在创建<code>OhMyWorker</code>对象后手动调用<code>ohMyWorker.init()</code>方法完成初始化即可。</p>
<hr>
<p><strong>OhMyScheduler日志单独配置</strong></p>
<p>目前OhMyScheduler-Worker并没有实现自己的LogFactory如果有需求的话请提ISSUE可以考虑实现原因如下</p>
<ol>
<li>OhMyScheduler-Worker的日志基于<code>Slf4J</code>输出即采用了基于门面设计模式的日志框架宿主应用无论如何都可以搭起Slf4J与实际的日志框架这座桥梁。</li>
<li>减轻了部分开发工作量不再需要实现自己的LogFactory虽然不怎么难就是了&hellip;)。</li>
</ol>
<p>为此为了顺利且友好地输出日志请在日志配置文件logback.xml/log4j2.xml/&hellip;)中为<code>OhMyScheduler-Worker</code>单独进行日志配置比如logback示例</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-xml" data-lang="xml"><span style="color:#f92672">&lt;appender</span> <span style="color:#a6e22e">name=</span><span style="color:#e6db74">&#34;OMS_WORKER_APPENDER&#34;</span> <span style="color:#a6e22e">class=</span><span style="color:#e6db74">&#34;ch.qos.logback.core.rolling.RollingFileAppender&#34;</span><span style="color:#f92672">&gt;</span>
<span style="color:#f92672">&lt;file&gt;</span>${LOG_PATH}/oms-worker.log<span style="color:#f92672">&lt;/file&gt;</span>
<span style="color:#f92672">&lt;rollingPolicy</span> <span style="color:#a6e22e">class=</span><span style="color:#e6db74">&#34;ch.qos.logback.core.rolling.TimeBasedRollingPolicy&#34;</span><span style="color:#f92672">&gt;</span>
<span style="color:#f92672">&lt;FileNamePattern&gt;</span>${LOG_PATH}/oms-worker.%d{yyyy-MM-dd}.log<span style="color:#f92672">&lt;/FileNamePattern&gt;</span>
<span style="color:#f92672">&lt;MaxHistory&gt;</span>7<span style="color:#f92672">&lt;/MaxHistory&gt;</span>
<span style="color:#f92672">&lt;/rollingPolicy&gt;</span>
<span style="color:#f92672">&lt;encoder</span> <span style="color:#a6e22e">class=</span><span style="color:#e6db74">&#34;ch.qos.logback.classic.encoder.PatternLayoutEncoder&#34;</span><span style="color:#f92672">&gt;</span>
<span style="color:#f92672">&lt;pattern&gt;</span>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n<span style="color:#f92672">&lt;/pattern&gt;</span>
<span style="color:#f92672">&lt;charset&gt;</span>UTF-8<span style="color:#f92672">&lt;/charset&gt;</span>
<span style="color:#f92672">&lt;/encoder&gt;</span>
<span style="color:#f92672">&lt;append&gt;</span>true<span style="color:#f92672">&lt;/append&gt;</span>
<span style="color:#f92672">&lt;/appender&gt;</span>
<span style="color:#f92672">&lt;logger</span> <span style="color:#a6e22e">name=</span><span style="color:#e6db74">&#34;com.github.kfcfans.oms.worker&#34;</span> <span style="color:#a6e22e">level=</span><span style="color:#e6db74">&#34;INFO&#34;</span> <span style="color:#a6e22e">additivity=</span><span style="color:#e6db74">&#34;false&#34;</span><span style="color:#f92672">&gt;</span>
<span style="color:#f92672">&lt;appender-ref</span> <span style="color:#a6e22e">ref=</span><span style="color:#e6db74">&#34;OMS_WORKER_APPENDER&#34;</span> <span style="color:#f92672">/&gt;</span>
<span style="color:#f92672">&lt;/logger&gt;</span>
</code></pre></div><p>无论如何OhMyScheduler-Worker启动时都会打印Banner如下所示您可以通过Banner来判断日志配置是否成功emmm&hellip;Markdown显示似乎有点丑实际上超帅的呢</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text"> ███████ ██ ████ ████ ████████ ██ ██ ██
██░░░░░██ ░██ ░██░██ ██░██ ██ ██ ██░░░░░░ ░██ ░██ ░██
██ ░░██░██ ░██░░██ ██ ░██ ░░██ ██ ░██ █████ ░██ █████ ░██ ██ ██ ░██ █████ ██████
░██ ░██░██████ ░██ ░░███ ░██ ░░███ ░█████████ ██░░░██░██████ ██░░░██ ██████░██ ░██ ░██ ██░░░██░░██░░█
░██ ░██░██░░░██░██ ░░█ ░██ ░██ ░░░░░░░░██░██ ░░ ░██░░░██░███████ ██░░░██░██ ░██ ░██░███████ ░██ ░
░░██ ██ ░██ ░██░██ ░ ░██ ██ ░██░██ ██░██ ░██░██░░░░ ░██ ░██░██ ░██ ░██░██░░░░ ░██
░░███████ ░██ ░██░██ ░██ ██ ████████ ░░█████ ░██ ░██░░██████░░██████░░██████ ███░░██████░███
░░░░░░░ ░░ ░░ ░░ ░░ ░░ ░░░░░░░░ ░░░░░ ░░ ░░ ░░░░░░ ░░░░░░ ░░░░░░ ░░░ ░░░░░░ ░░░
</code></pre></div><h2 id="基于agent的执行器初始化">基于agent的执行器初始化</h2>
<blockquote>
<p>agent是一个没有任何业务逻辑的执行器其实就是为worker加了一个main方法</p>
</blockquote>
<p>代码编译方式启动示例:<code>java -jar oh-my-scheduler-worker-agent-1.2.0.jar -a my-agent</code></p>
<pre><code>Usage: OhMyAgent [-hV] -a=&lt;appName&gt; [-e=&lt;storeStrategy&gt;] [-l=&lt;length&gt;]
[-p=&lt;port&gt;] [-s=&lt;server&gt;]
OhMyScheduler-Worker代理
-a, --app=&lt;appName&gt; worker-agent名称可通过调度中心控制台创建
-e, --persistence=&lt;storeStrategy&gt;
存储策略枚举值DISK 或 MEMORY
-h, --help Show this help message and exit.
-l, --length=&lt;length&gt; 返回值最大长度
-p, --port=&lt;port&gt; worker-agent的ActorSystem监听端口不建议更改
-s, --server=&lt;server&gt; 调度中心地址,多值英文逗号分隔,格式 IP:Port OR domain
-V, --version Print version information and exit.
</code></pre><p>Docker镜像<a href="https://hub.docker.com/r/tjqq/oms-agent">Docker Hub</a></p>
</article>
<footer class="book-footer">
<div class="flex flex-wrap justify-between">
</div>
</footer>
<div class="book-comments">
</div>
<label for="menu-control" class="hidden book-menu-overlay"></label>
</div>
<aside class="book-toc">
<nav id="TableOfContents">
<ul>
<li><a href="#基于宿主应用的执行器初始化">基于宿主应用的执行器初始化</a></li>
<li><a href="#基于agent的执行器初始化">基于agent的执行器初始化</a></li>
</ul>
</nav>
</aside>
</main>
</body>
</html>

View File

@ -0,0 +1,612 @@
<!DOCTYPE html>
<html lang="en" dir=>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="处理器概述 OhMyScheduler当前支持ShellPython等脚本处理器和Java处理器脚本处理器只需要开发者完成脚本的编写xxx.sh / xxx.py在控制台填入脚本内容即可本章不再赘述本章将重点阐述Java处理器开发方法与使用技巧
Java处理器可根据代码所处位置划分为内置Java处理器和容器Java处理器前者直接集成在宿主应用也就是接入本系统的业务应用一般用来处理业务需求后者可以在一个独立的轻量级的Java工程中开发通过容器技术详见容器章节被worker集群热加载提供Java的“脚本能力”一般用于处理灵活多变的需求。 Java处理器可根据对象创建者划分为SpringBean处理器和普通Java对象处理器前者由Spring IOC容器完成处理器的创建和初始化后者则有OhMyScheduler维护其状态。如果宿主应用支持Spring强烈建议使用SpringBean处理器开发者仅需要将Processor注册进Spring IOC容器一个@Component注解或一句bean配置。 Java处理器可根据功能划分为单机处理器、广播处理器、Map处理器和MapReduce处理器。 单机处理器BasicProcessor对应了单机任务即某个任务的某次运行只会有某一台机器的某一个线程参与运算。 广播处理器BroadcastProcessor对应了广播任务即某个任务的某次运行会调动集群内所有机器参与运算。 Map处理器MapProcessor对应了Map任务即某个任务在运行过程中允许产生子任务并分发到其他机器进行运算。 MapReduce处理器MapReduceProcessor对应了MapReduce任务在Map任务的基础上增加了所有任务结束后的汇总统计。 核心方法process 任意Java处理器都需要实现处理的核心方法其接口签名如下
ProcessResult process(TaskContext context) throws Exception; 方法入参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造成巨大的压力 方法的返回值为ProcessResult代表了本次Task执行的结果包含success和msg两个属性分别用于传递Task是否执行成功和Task需要返回的信息。">
<meta name="theme-color" content="#FFFFFF"><meta property="og:title" content="处理器开发" />
<meta property="og:description" content="处理器概述 OhMyScheduler当前支持ShellPython等脚本处理器和Java处理器脚本处理器只需要开发者完成脚本的编写xxx.sh / xxx.py在控制台填入脚本内容即可本章不再赘述本章将重点阐述Java处理器开发方法与使用技巧
Java处理器可根据代码所处位置划分为内置Java处理器和容器Java处理器前者直接集成在宿主应用也就是接入本系统的业务应用一般用来处理业务需求后者可以在一个独立的轻量级的Java工程中开发通过容器技术详见容器章节被worker集群热加载提供Java的“脚本能力”一般用于处理灵活多变的需求。 Java处理器可根据对象创建者划分为SpringBean处理器和普通Java对象处理器前者由Spring IOC容器完成处理器的创建和初始化后者则有OhMyScheduler维护其状态。如果宿主应用支持Spring强烈建议使用SpringBean处理器开发者仅需要将Processor注册进Spring IOC容器一个@Component注解或一句bean配置。 Java处理器可根据功能划分为单机处理器、广播处理器、Map处理器和MapReduce处理器。 单机处理器BasicProcessor对应了单机任务即某个任务的某次运行只会有某一台机器的某一个线程参与运算。 广播处理器BroadcastProcessor对应了广播任务即某个任务的某次运行会调动集群内所有机器参与运算。 Map处理器MapProcessor对应了Map任务即某个任务在运行过程中允许产生子任务并分发到其他机器进行运算。 MapReduce处理器MapReduceProcessor对应了MapReduce任务在Map任务的基础上增加了所有任务结束后的汇总统计。 核心方法process 任意Java处理器都需要实现处理的核心方法其接口签名如下
ProcessResult process(TaskContext context) throws Exception; 方法入参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造成巨大的压力 方法的返回值为ProcessResult代表了本次Task执行的结果包含success和msg两个属性分别用于传递Task是否执行成功和Task需要返回的信息。" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://kfcfans.gitee.io/ohmyscheduler/docs/startup/3-processor-develop/" />
<title>处理器开发 | OhMyScheduler</title>
<link rel="manifest" href="/ohmyscheduler/manifest.json">
<link rel="icon" href="/ohmyscheduler/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="/ohmyscheduler/book.min.e161f1fe2b283b6a43c29a52fde96e2387fade573e78efa6701d44c8499da76b.css" integrity="sha256-4WHx/isoO2pDwppS/eluI4f63lc&#43;eO&#43;mcB1EyEmdp2s=">
<script defer src="/ohmyscheduler/en.search.min.e2f9b2f3cf3fad006da31fc1558075ea0493c82e60c3b707d1745af9a528b273.js" integrity="sha256-4vmy888/rQBtox/BVYB16gSTyC5gw7cH0XRa&#43;aUosnM="></script>
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
</head>
<body dir=>
<input type="checkbox" class="hidden" id="menu-control" />
<main class="container flex">
<aside class="book-menu">
<nav>
<h2 class="book-brand">
<a href="/ohmyscheduler"><span>OhMyScheduler</span>
</a>
</h2>
<div class="book-search">
<input type="text" id="book-search-input" placeholder="Search" aria-label="Search" maxlength="64" data-hotkeys="s/" />
<div class="book-search-spinner hidden"></div>
<ul id="book-search-results"></ul>
</div>
<ul>
<li>
<span>快速开始</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/startup/1-server-startup/" class="">调度中心Server部署</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/2-worker-startup/" class="">执行器Worker初始化</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/3-processor-develop/" class="active">处理器开发</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/4-console-guide/" class="">任务管理与在线运维</a>
</li>
</ul>
</li>
<li>
<span>高级特性</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/super/container/" class="">容器</a>
</li>
<li>
<a href="/ohmyscheduler/docs/super/openapi/" class="">OpenAPI</a>
</li>
</ul>
</li>
<li>
<span>更新日志</span>
<ul>
</ul>
</li>
</ul>
</nav>
<script>(function(){var menu=document.querySelector("aside.book-menu nav");addEventListener("beforeunload",function(event){localStorage.setItem("menu.scrollTop",menu.scrollTop);});menu.scrollTop=localStorage.getItem("menu.scrollTop");})();</script>
</aside>
<div class="book-page">
<header class="book-header">
<div class="flex align-center justify-between">
<label for="menu-control">
<img src="/ohmyscheduler/svg/menu.svg" class="book-icon" alt="Menu" />
</label>
<strong>处理器开发</strong>
<label for="toc-control">
<img src="/ohmyscheduler/svg/toc.svg" class="book-icon" alt="Table of Contents" />
</label>
</div>
<input type="checkbox" class="hidden" id="toc-control" />
<aside class="hidden clearfix">
<nav id="TableOfContents">
<ul>
<li><a href="#处理器概述">处理器概述</a></li>
<li><a href="#核心方法process">核心方法process</a></li>
<li><a href="#单机处理器basicprocessor">单机处理器BasicProcessor</a></li>
<li><a href="#广播处理器broadcastprocessor">广播处理器BroadcastProcessor</a></li>
<li><a href="#并行处理器mapreduceprocessor">并行处理器MapReduceProcessor</a></li>
<li><a href="#最佳实践mapreduce实现静态分片">最佳实践MapReduce实现静态分片</a></li>
<li><a href="#最佳实践mapreduce多级分发处理">最佳实践MapReduce多级分发处理</a></li>
<li><a href="#更多示例">更多示例</a></li>
</ul>
</nav>
</aside>
</header>
<article class="markdown"><h2 id="处理器概述">处理器概述</h2>
<blockquote>
<p>OhMyScheduler当前支持Shell、Python等脚本处理器和Java处理器。脚本处理器只需要开发者完成脚本的编写xxx.sh / xxx.py在控制台填入脚本内容即可本章不再赘述。本章将重点阐述Java处理器开发方法与使用技巧。</p>
</blockquote>
<ul>
<li>Java处理器可根据<strong>代码所处位置</strong>划分为内置Java处理器和容器Java处理器前者直接集成在宿主应用也就是接入本系统的业务应用一般用来处理业务需求后者可以在一个独立的轻量级的Java工程中开发通过<strong>容器技术</strong>详见容器章节被worker集群热加载提供Java的“脚本能力”一般用于处理灵活多变的需求。</li>
<li>Java处理器可根据<strong>对象创建者</strong>划分为SpringBean处理器和普通Java对象处理器前者由Spring IOC容器完成处理器的创建和初始化后者则有OhMyScheduler维护其状态。如果宿主应用支持Spring<strong>强烈建议使用SpringBean处理器</strong>开发者仅需要将Processor注册进Spring IOC容器一个<code>@Component</code>注解或一句<code>bean</code>配置)。</li>
<li>Java处理器可根据<strong>功能</strong>划分为单机处理器、广播处理器、Map处理器和MapReduce处理器。
<ul>
<li>单机处理器(<code>BasicProcessor</code>)对应了单机任务,即某个任务的某次运行只会有某一台机器的某一个线程参与运算。</li>
<li>广播处理器(<code>BroadcastProcessor</code>)对应了广播任务,即某个任务的某次运行会<strong>调动集群内所有机器参与运算</strong></li>
<li>Map处理器<code>MapProcessor</code>对应了Map任务即某个任务在运行过程中<strong>允许产生子任务并分发到其他机器进行运算</strong></li>
<li>MapReduce处理器<code>MapReduceProcessor</code>对应了MapReduce任务在Map任务的基础上<strong>增加了所有任务结束后的汇总统计</strong></li>
</ul>
</li>
</ul>
<h2 id="核心方法process">核心方法process</h2>
<p>任意Java处理器都需要实现处理的核心方法其接口签名如下</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java">ProcessResult <span style="color:#a6e22e">process</span><span style="color:#f92672">(</span>TaskContext context<span style="color:#f92672">)</span> <span style="color:#66d9ef">throws</span> Exception<span style="color:#f92672">;</span>
</code></pre></div><p>方法入参<code>TaskContext</code>,包含了本次处理的上下文信息,具体属性如下:</p>
<table>
<thead>
<tr>
<th>属性名称</th>
<th>意义/用法</th>
</tr>
</thead>
<tbody>
<tr>
<td>jobId</td>
<td>任务ID开发者一般无需关心此参数</td>
</tr>
<tr>
<td>instanceId</td>
<td>任务实例ID全局唯一开发者一般无需关心此参数</td>
</tr>
<tr>
<td>subInstanceId</td>
<td>子任务实例ID秒级任务使用开发者一般无需关心此参数</td>
</tr>
<tr>
<td>taskId</td>
<td>采用链式命名法的ID在某个任务实例内唯一开发者一般无需关心此参数</td>
</tr>
<tr>
<td>taskName</td>
<td>task名称Map/MapReduce任务的子任务的值为开发者指定否则为系统默认值开发者一般无需关心此参数</td>
</tr>
<tr>
<td>jobParams</td>
<td>任务参数,其值等同于控制台录入的<strong>任务参数</strong>,常用!</td>
</tr>
<tr>
<td>instanceParams</td>
<td>任务实例参数其值等同于使用OpenAPI运行任务实例时传递的参数常用</td>
</tr>
<tr>
<td>maxRetryTimes</td>
<td>Task的最大重试次数</td>
</tr>
<tr>
<td>currentRetryTimes</td>
<td>Task的当前重试次数和maxRetryTimes联合起来可以判断当前是否为该Task的最后一次运行机会</td>
</tr>
<tr>
<td>subTask</td>
<td>子TaskMap/MapReduce处理器专属开发者调用map方法时传递的子任务列表中的某一个</td>
</tr>
<tr>
<td>omsLogger</td>
<td>在线日志用法同Slf4J记录的日志可以直接通过控制台查看非常便捷和强大不过使用过程中需要注意频率可能对Server造成巨大的压力</td>
</tr>
</tbody>
</table>
<p>方法的返回值为<code>ProcessResult</code>代表了本次Task执行的结果包含<code>success</code><code>msg</code>两个属性分别用于传递Task是否执行成功和Task需要返回的信息。</p>
<h2 id="单机处理器basicprocessor">单机处理器BasicProcessor</h2>
<p>单机执行的策略下server会在所有可用worker中选取健康度最佳的机器进行执行。单机执行任务需要实现接口<code>BasicProcessor</code>,代码示例如下:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#75715e">// 支持 SpringBean 的形式
</span><span style="color:#75715e"></span><span style="color:#a6e22e">@Component</span>
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">BasicProcessorDemo</span> <span style="color:#66d9ef">implements</span> BasicProcessor <span style="color:#f92672">{</span>
<span style="color:#a6e22e">@Resource</span>
<span style="color:#66d9ef">private</span> MysteryService mysteryService<span style="color:#f92672">;</span>
<span style="color:#a6e22e">@Override</span>
<span style="color:#66d9ef">public</span> ProcessResult <span style="color:#a6e22e">process</span><span style="color:#f92672">(</span>TaskContext context<span style="color:#f92672">)</span> <span style="color:#66d9ef">throws</span> Exception <span style="color:#f92672">{</span>
<span style="color:#75715e">// 在线日志功能,可以直接在控制台查看任务日志,非常便捷
</span><span style="color:#75715e"></span> OmsLogger omsLogger <span style="color:#f92672">=</span> context<span style="color:#f92672">.</span><span style="color:#a6e22e">getOmsLogger</span><span style="color:#f92672">();</span>
omsLogger<span style="color:#f92672">.</span><span style="color:#a6e22e">info</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;BasicProcessorDemo start to process, current JobParams is {}.&#34;</span><span style="color:#f92672">,</span> context<span style="color:#f92672">.</span><span style="color:#a6e22e">getJobParams</span><span style="color:#f92672">());</span>
<span style="color:#75715e">// TaskContext为任务的上下文信息包含了在控制台录入的任务元数据常用字段为
</span><span style="color:#75715e"></span> <span style="color:#75715e">// jobParams任务参数在控制台录入instanceParams任务实例参数通过 OpenAPI 触发的任务实例才可能存在该参数)
</span><span style="color:#75715e"></span>
<span style="color:#75715e">// 进行实际处理...
</span><span style="color:#75715e"></span> mysteryService<span style="color:#f92672">.</span><span style="color:#a6e22e">hasaki</span><span style="color:#f92672">();</span>
<span style="color:#75715e">// 返回结果,该结果会被持久化到数据库,在前端页面直接查看,极为方便
</span><span style="color:#75715e"></span> <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> ProcessResult<span style="color:#f92672">(</span><span style="color:#66d9ef">true</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;result is xxx&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
<span style="color:#f92672">}</span>
</code></pre></div><h2 id="广播处理器broadcastprocessor">广播处理器BroadcastProcessor</h2>
<p>广播执行的策略下,所有机器都会被调度执行该任务。为了便于资源的准备和释放,广播处理器在<code>BasicProcessor</code>的基础上额外增加了<code>preProcess</code><code>postProcess</code>方法,分别在整个集群开始之前/结束之后<strong>选一台机器</strong>执行相关方法。代码示例如下:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#a6e22e">@Component</span>
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">BroadcastProcessorDemo</span> <span style="color:#66d9ef">extends</span> BroadcastProcessor <span style="color:#f92672">{</span>
<span style="color:#a6e22e">@Override</span>
<span style="color:#66d9ef">public</span> ProcessResult <span style="color:#a6e22e">preProcess</span><span style="color:#f92672">(</span>TaskContext taskContext<span style="color:#f92672">)</span> <span style="color:#66d9ef">throws</span> Exception <span style="color:#f92672">{</span>
<span style="color:#75715e">// 预执行,会在所有 worker 执行 process 方法前调用
</span><span style="color:#75715e"></span> <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> ProcessResult<span style="color:#f92672">(</span><span style="color:#66d9ef">true</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;init success&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
<span style="color:#a6e22e">@Override</span>
<span style="color:#66d9ef">public</span> ProcessResult <span style="color:#a6e22e">process</span><span style="color:#f92672">(</span>TaskContext context<span style="color:#f92672">)</span> <span style="color:#66d9ef">throws</span> Exception <span style="color:#f92672">{</span>
<span style="color:#75715e">// 撰写整个worker集群都会执行的代码逻辑
</span><span style="color:#75715e"></span> <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> ProcessResult<span style="color:#f92672">(</span><span style="color:#66d9ef">true</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;release resource success&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
<span style="color:#a6e22e">@Override</span>
<span style="color:#66d9ef">public</span> ProcessResult <span style="color:#a6e22e">postProcess</span><span style="color:#f92672">(</span>TaskContext taskContext<span style="color:#f92672">,</span> List<span style="color:#f92672">&lt;</span>TaskResult<span style="color:#f92672">&gt;</span> taskResults<span style="color:#f92672">)</span> <span style="color:#66d9ef">throws</span> Exception <span style="color:#f92672">{</span>
<span style="color:#75715e">// taskResults 存储了所有worker执行的结果包括preProcess
</span><span style="color:#75715e"></span>
<span style="color:#75715e">// 收尾,会在所有 worker 执行完毕 process 方法后调用,该结果将作为最终的执行结果
</span><span style="color:#75715e"></span> <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> ProcessResult<span style="color:#f92672">(</span><span style="color:#66d9ef">true</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;process success&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
<span style="color:#f92672">}</span>
</code></pre></div><h2 id="并行处理器mapreduceprocessor">并行处理器MapReduceProcessor</h2>
<p>MapReduce是最复杂也是最强大的一种执行器它允许开发者完成任务的拆分将子任务派发到集群中其他Worker执行是执行大批量处理任务的不二之选实现MapReduce处理器需要继承<code>MapReduceProcessor</code>类,具体用法如下示例代码所示:</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#a6e22e">@Component</span>
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">MapReduceProcessorDemo</span> <span style="color:#66d9ef">extends</span> MapReduceProcessor <span style="color:#f92672">{</span>
<span style="color:#a6e22e">@Override</span>
<span style="color:#66d9ef">public</span> ProcessResult <span style="color:#a6e22e">process</span><span style="color:#f92672">(</span>TaskContext context<span style="color:#f92672">)</span> <span style="color:#66d9ef">throws</span> Exception <span style="color:#f92672">{</span>
<span style="color:#75715e">// 判断是否为根任务
</span><span style="color:#75715e"></span> <span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>isRootTask<span style="color:#f92672">())</span> <span style="color:#f92672">{</span>
<span style="color:#75715e">// 构造子任务
</span><span style="color:#75715e"></span> List<span style="color:#f92672">&lt;</span>SubTask<span style="color:#f92672">&gt;</span> subTaskList <span style="color:#f92672">=</span> Lists<span style="color:#f92672">.</span><span style="color:#a6e22e">newLinkedList</span><span style="color:#f92672">();</span>
<span style="color:#75715e">/*
</span><span style="color:#75715e"> * 子任务的构造由开发者自己定义
</span><span style="color:#75715e"> * eg. 现在需要从文件中读取100W个ID并处理数据库中这些ID对应的数据那么步骤如下
</span><span style="color:#75715e"> * 1. 根任务RootTask读取文件流式拉取100W个ID并按1000个一批的大小组装成子任务进行派发
</span><span style="color:#75715e"> * 2. 非根任务获取子任务,完成业务逻辑的处理
</span><span style="color:#75715e"> */</span>
<span style="color:#75715e">// 调用 map 方法,派发子任务
</span><span style="color:#75715e"></span> <span style="color:#66d9ef">return</span> map<span style="color:#f92672">(</span>subTaskList<span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;DATA_PROCESS_TASK&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
<span style="color:#75715e">// 非子任务,可根据 subTask 的类型 或 TaskName 来判断分支
</span><span style="color:#75715e"></span> <span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>context<span style="color:#f92672">.</span><span style="color:#a6e22e">getSubTask</span><span style="color:#f92672">()</span> <span style="color:#66d9ef">instanceof</span> SubTask<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
<span style="color:#75715e">// 执行子任务,注:子任务人可以 map 产生新的子任务,可以构建任意级的 MapReduce 处理器
</span><span style="color:#75715e"></span> <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> ProcessResult<span style="color:#f92672">(</span><span style="color:#66d9ef">true</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;PROCESS_SUB_TASK_SUCCESS&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> ProcessResult<span style="color:#f92672">(</span><span style="color:#66d9ef">false</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;UNKNOWN_BUG&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
<span style="color:#a6e22e">@Override</span>
<span style="color:#66d9ef">public</span> ProcessResult <span style="color:#a6e22e">reduce</span><span style="color:#f92672">(</span>TaskContext taskContext<span style="color:#f92672">,</span> List<span style="color:#f92672">&lt;</span>TaskResult<span style="color:#f92672">&gt;</span> taskResults<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
<span style="color:#75715e">// 所有 Task 执行结束后reduce 将会被执行
</span><span style="color:#75715e"></span> <span style="color:#75715e">// taskResults 保存了所有子任务的执行结果
</span><span style="color:#75715e"></span>
<span style="color:#75715e">// 用法举例,统计执行结果
</span><span style="color:#75715e"></span> AtomicLong successCnt <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> AtomicLong<span style="color:#f92672">(</span>0<span style="color:#f92672">);</span>
taskResults<span style="color:#f92672">.</span><span style="color:#a6e22e">forEach</span><span style="color:#f92672">(</span>tr <span style="color:#f92672">-&gt;</span> <span style="color:#f92672">{</span>
<span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>tr<span style="color:#f92672">.</span><span style="color:#a6e22e">isSuccess</span><span style="color:#f92672">())</span> <span style="color:#f92672">{</span>
successCnt<span style="color:#f92672">.</span><span style="color:#a6e22e">incrementAndGet</span><span style="color:#f92672">();</span>
<span style="color:#f92672">}</span>
<span style="color:#f92672">});</span>
<span style="color:#75715e">// 该结果将作为任务最终的执行结果
</span><span style="color:#75715e"></span> <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> ProcessResult<span style="color:#f92672">(</span><span style="color:#66d9ef">true</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;success task num:&#34;</span> <span style="color:#f92672">+</span> successCnt<span style="color:#f92672">.</span><span style="color:#a6e22e">get</span><span style="color:#f92672">());</span>
<span style="color:#f92672">}</span>
<span style="color:#75715e">// 自定义的子任务
</span><span style="color:#75715e"></span> <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">SubTask</span> <span style="color:#f92672">{</span>
<span style="color:#66d9ef">private</span> Long siteId<span style="color:#f92672">;</span>
<span style="color:#66d9ef">private</span> List<span style="color:#f92672">&lt;</span>Long<span style="color:#f92672">&gt;</span> idList<span style="color:#f92672">;</span>
<span style="color:#f92672">}</span>
<span style="color:#f92672">}</span>
</code></pre></div><p>Map处理器相当于MapReduce处理器的阉割版本阉割了<code>reduce</code>方法),此处不再单独举例。</p>
<h2 id="最佳实践mapreduce实现静态分片">最佳实践MapReduce实现静态分片</h2>
<p>虽然说这有点傻鸡焉用牛刀的感觉,不过既然目前市场上同类产品都处于静态分片的阶段,我也就在这里给大家举个例子吧~</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#a6e22e">@Component</span>
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">StaticSliceProcessor</span> <span style="color:#66d9ef">extends</span> MapReduceProcessor <span style="color:#f92672">{</span>
<span style="color:#a6e22e">@Override</span>
<span style="color:#66d9ef">public</span> ProcessResult <span style="color:#a6e22e">process</span><span style="color:#f92672">(</span>TaskContext context<span style="color:#f92672">)</span> <span style="color:#66d9ef">throws</span> Exception <span style="color:#f92672">{</span>
OmsLogger omsLogger <span style="color:#f92672">=</span> context<span style="color:#f92672">.</span><span style="color:#a6e22e">getOmsLogger</span><span style="color:#f92672">();</span>
<span style="color:#75715e">// root task 负责分发任务
</span><span style="color:#75715e"></span> <span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>isRootTask<span style="color:#f92672">())</span> <span style="color:#f92672">{</span>
<span style="color:#75715e">// 从控制台传递分片参数架设格式为KV1=a&amp;2=b&amp;3=c
</span><span style="color:#75715e"></span> String jobParams <span style="color:#f92672">=</span> context<span style="color:#f92672">.</span><span style="color:#a6e22e">getJobParams</span><span style="color:#f92672">();</span>
Map<span style="color:#f92672">&lt;</span>String<span style="color:#f92672">,</span> String<span style="color:#f92672">&gt;</span> paramsMap <span style="color:#f92672">=</span> Splitter<span style="color:#f92672">.</span><span style="color:#a6e22e">on</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;&amp;&#34;</span><span style="color:#f92672">).</span><span style="color:#a6e22e">withKeyValueSeparator</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;=&#34;</span><span style="color:#f92672">).</span><span style="color:#a6e22e">split</span><span style="color:#f92672">(</span>jobParams<span style="color:#f92672">);</span>
List<span style="color:#f92672">&lt;</span>SubTask<span style="color:#f92672">&gt;</span> subTasks <span style="color:#f92672">=</span> Lists<span style="color:#f92672">.</span><span style="color:#a6e22e">newLinkedList</span><span style="color:#f92672">();</span>
paramsMap<span style="color:#f92672">.</span><span style="color:#a6e22e">forEach</span><span style="color:#f92672">((</span>k<span style="color:#f92672">,</span> v<span style="color:#f92672">)</span> <span style="color:#f92672">-&gt;</span> subTasks<span style="color:#f92672">.</span><span style="color:#a6e22e">add</span><span style="color:#f92672">(</span><span style="color:#66d9ef">new</span> SubTask<span style="color:#f92672">(</span>Integer<span style="color:#f92672">.</span><span style="color:#a6e22e">parseInt</span><span style="color:#f92672">(</span>k<span style="color:#f92672">),</span> v<span style="color:#f92672">)));</span>
<span style="color:#66d9ef">return</span> map<span style="color:#f92672">(</span>subTasks<span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;SLICE_TASK&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
Object subTask <span style="color:#f92672">=</span> context<span style="color:#f92672">.</span><span style="color:#a6e22e">getSubTask</span><span style="color:#f92672">();</span>
<span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>subTask <span style="color:#66d9ef">instanceof</span> SubTask<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
<span style="color:#75715e">// 实际处理
</span><span style="color:#75715e"></span> <span style="color:#75715e">// 当然,如果觉得 subTask 还是很大,也可以继续分发哦
</span><span style="color:#75715e"></span>
<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> ProcessResult<span style="color:#f92672">(</span><span style="color:#66d9ef">true</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;subTask:&#34;</span> <span style="color:#f92672">+</span> <span style="color:#f92672">((</span>SubTask<span style="color:#f92672">)</span> subTask<span style="color:#f92672">).</span><span style="color:#a6e22e">getIndex</span><span style="color:#f92672">()</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34; process successfully&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> ProcessResult<span style="color:#f92672">(</span><span style="color:#66d9ef">false</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;UNKNOWN BUG&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
<span style="color:#a6e22e">@Override</span>
<span style="color:#66d9ef">public</span> ProcessResult <span style="color:#a6e22e">reduce</span><span style="color:#f92672">(</span>TaskContext context<span style="color:#f92672">,</span> List<span style="color:#f92672">&lt;</span>TaskResult<span style="color:#f92672">&gt;</span> taskResults<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
<span style="color:#75715e">// 按需求做一些统计工作... 不需要的话,直接使用 Map 处理器即可
</span><span style="color:#75715e"></span> <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> ProcessResult<span style="color:#f92672">(</span><span style="color:#66d9ef">true</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;xxxx&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
<span style="color:#a6e22e">@Getter</span>
<span style="color:#a6e22e">@NoArgsConstructor</span>
<span style="color:#a6e22e">@AllArgsConstructor</span>
<span style="color:#66d9ef">private</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">SubTask</span> <span style="color:#f92672">{</span>
<span style="color:#66d9ef">private</span> <span style="color:#66d9ef">int</span> index<span style="color:#f92672">;</span>
<span style="color:#66d9ef">private</span> String params<span style="color:#f92672">;</span>
<span style="color:#f92672">}</span>
<span style="color:#f92672">}</span>
</code></pre></div><h2 id="最佳实践mapreduce多级分发处理">最佳实践MapReduce多级分发处理</h2>
<p>利用MapReduce实现 Root -&gt; A -&gt; B/C -&gt; Reduce的DAG 工作流。</p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#a6e22e">@Component</span>
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">DAGSimulationProcessor</span> <span style="color:#66d9ef">extends</span> MapReduceProcessor <span style="color:#f92672">{</span>
<span style="color:#a6e22e">@Override</span>
<span style="color:#66d9ef">public</span> ProcessResult <span style="color:#a6e22e">process</span><span style="color:#f92672">(</span>TaskContext context<span style="color:#f92672">)</span> <span style="color:#66d9ef">throws</span> Exception <span style="color:#f92672">{</span>
<span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>isRootTask<span style="color:#f92672">())</span> <span style="color:#f92672">{</span>
<span style="color:#75715e">// L1. 执行根任务
</span><span style="color:#75715e"></span>
<span style="color:#75715e">// 执行完毕后产生子任务 A需要传递的参数可以作为 TaskA 的属性进行传递
</span><span style="color:#75715e"></span> TaskA taskA <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> TaskA<span style="color:#f92672">();</span>
<span style="color:#66d9ef">return</span> map<span style="color:#f92672">(</span>Lists<span style="color:#f92672">.</span><span style="color:#a6e22e">newArrayList</span><span style="color:#f92672">(</span>taskA<span style="color:#f92672">),</span> <span style="color:#e6db74">&#34;LEVEL1_TASK_A&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
<span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>context<span style="color:#f92672">.</span><span style="color:#a6e22e">getSubTask</span><span style="color:#f92672">()</span> <span style="color:#66d9ef">instanceof</span> TaskA<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
<span style="color:#75715e">// L2. 执行A任务
</span><span style="color:#75715e"></span>
<span style="color:#75715e">// 执行完成后产生子任务 BC并行执行
</span><span style="color:#75715e"></span> TaskB taskB <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> TaskB<span style="color:#f92672">();</span>
TaskC taskC <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> TaskC<span style="color:#f92672">();</span>
<span style="color:#66d9ef">return</span> map<span style="color:#f92672">(</span>Lists<span style="color:#f92672">.</span><span style="color:#a6e22e">newArrayList</span><span style="color:#f92672">(</span>taskB<span style="color:#f92672">,</span> taskC<span style="color:#f92672">),</span> <span style="color:#e6db74">&#34;LEVEL2_TASK_BC&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
<span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>context<span style="color:#f92672">.</span><span style="color:#a6e22e">getSubTask</span><span style="color:#f92672">()</span> <span style="color:#66d9ef">instanceof</span> TaskB<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
<span style="color:#75715e">// L3. 执行B任务
</span><span style="color:#75715e"></span> <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> ProcessResult<span style="color:#f92672">(</span><span style="color:#66d9ef">true</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;xxx&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
<span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>context<span style="color:#f92672">.</span><span style="color:#a6e22e">getSubTask</span><span style="color:#f92672">()</span> <span style="color:#66d9ef">instanceof</span> TaskC<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
<span style="color:#75715e">// L3. 执行C任务
</span><span style="color:#75715e"></span> <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> ProcessResult<span style="color:#f92672">(</span><span style="color:#66d9ef">true</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;xxx&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> ProcessResult<span style="color:#f92672">(</span><span style="color:#66d9ef">false</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;UNKNOWN_TYPE_OF_SUB_TASK&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
<span style="color:#a6e22e">@Override</span>
<span style="color:#66d9ef">public</span> ProcessResult <span style="color:#a6e22e">reduce</span><span style="color:#f92672">(</span>TaskContext context<span style="color:#f92672">,</span> List<span style="color:#f92672">&lt;</span>TaskResult<span style="color:#f92672">&gt;</span> taskResults<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
<span style="color:#75715e">// L4. 执行最终 Reduce 任务taskResults保存了之前所有任务的结果
</span><span style="color:#75715e"></span> taskResults<span style="color:#f92672">.</span><span style="color:#a6e22e">forEach</span><span style="color:#f92672">(</span>taskResult <span style="color:#f92672">-&gt;</span> <span style="color:#f92672">{</span>
<span style="color:#75715e">// do something...
</span><span style="color:#75715e"></span> <span style="color:#f92672">});</span>
<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">new</span> ProcessResult<span style="color:#f92672">(</span><span style="color:#66d9ef">true</span><span style="color:#f92672">,</span> <span style="color:#e6db74">&#34;reduce success&#34;</span><span style="color:#f92672">);</span>
<span style="color:#f92672">}</span>
<span style="color:#66d9ef">private</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">TaskA</span> <span style="color:#f92672">{</span>
<span style="color:#f92672">}</span>
<span style="color:#66d9ef">private</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">TaskB</span> <span style="color:#f92672">{</span>
<span style="color:#f92672">}</span>
<span style="color:#66d9ef">private</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">TaskC</span> <span style="color:#f92672">{</span>
<span style="color:#f92672">}</span>
<span style="color:#f92672">}</span>
</code></pre></div><h2 id="更多示例">更多示例</h2>
<p>没看够?更多示例请见:<a href="https://github.com/KFCFans/OhMyScheduler/tree/master/oh-my-scheduler-worker-samples">oh-my-scheduler-worker-samples</a></p>
</article>
<footer class="book-footer">
<div class="flex flex-wrap justify-between">
</div>
</footer>
<div class="book-comments">
</div>
<label for="menu-control" class="hidden book-menu-overlay"></label>
</div>
<aside class="book-toc">
<nav id="TableOfContents">
<ul>
<li><a href="#处理器概述">处理器概述</a></li>
<li><a href="#核心方法process">核心方法process</a></li>
<li><a href="#单机处理器basicprocessor">单机处理器BasicProcessor</a></li>
<li><a href="#广播处理器broadcastprocessor">广播处理器BroadcastProcessor</a></li>
<li><a href="#并行处理器mapreduceprocessor">并行处理器MapReduceProcessor</a></li>
<li><a href="#最佳实践mapreduce实现静态分片">最佳实践MapReduce实现静态分片</a></li>
<li><a href="#最佳实践mapreduce多级分发处理">最佳实践MapReduce多级分发处理</a></li>
<li><a href="#更多示例">更多示例</a></li>
</ul>
</nav>
</aside>
</main>
</body>
</html>

View File

@ -0,0 +1,417 @@
<!DOCTYPE html>
<html lang="en" dir=>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="前端控制台允许开发者可视化地进行任务增、删、改、查等管理操作,同时也能直观地看到任务的运行数据,包括运行状态、详情和在线日志等。以下为对控制台的详细介绍: 主页 展示了系统整体的概览和集群Worker列表
任务创建 创建需要被调度执行的任务,入口为主页 -&gt; 任务管理 -&gt; 新建任务。
任务名称:名称,便于记忆与搜索,无特殊用途,请尽量简短(占用数据库字段空间)
任务描述:描述,无特殊作用,请尽量简短(占用数据库字段空间)
任务参数任务处理时能够获取到的参数即各个Processor的process方法入参TaskContext对象的jobParams字段进行一次处理器开发就能理解了
定时信息:由下拉框和输入框组成
API -&gt; 不需要填写任何参数(填了也不起作用) CRON -&gt; 填写 CRON 表达式(可以找个在线生成网站生成) 固定频率 -&gt; 填写整数,单位毫秒 固定延迟 -&gt; 填写整数,单位毫秒 执行配置由执行类型单机、广播和MapReduce、处理器类型和处理器参数组成后两项相互关联。
内置Java处理器 -&gt; 填写该处理器的全限定类名eg, com.github.kfcfans.oms.processors.demo.MapReduceProcessorDemo Java容器 -&gt; 填写容器ID#处理器全限定类名eg1#com.github.kfcfans.oms.container.DemoProcessor SHELL -&gt; 填写需要处理的脚本直接复制文件内容或脚本下载连接http://xxx PYTHON -&gt; 填写完整的python脚本或下载连接http://xxx 运行配置
最大实例数:该任务同时执行的数量(任务和实例就像是类和对象的关系,任务被调度执行后被称为实例) 单机线程并发数该实例执行过程中每个Worker使用的线程数量MapReduce任务生效其余无论填什么都只会使用1个线程或3个线程&hellip; 运行时间限制限定任务的最大运行时间超时则视为失败单位毫秒0代表不限制超时时间。 重试配置:
任务重试次数实例级别失败了整个任务实例重试会更换TaskTracker本次任务实例的Master节点代价较大大型Map/MapReduce慎用。 子任务重试次数Task级别每个子Task失败后单独重试会更换ProcessorTracker本次任务实际执行的Worker节点代价较小推荐使用。 注对于单机任务来说假如任务重试次数和子任务重试次数都配置了1且都执行失败实际执行次数会变成4次推荐任务实例重试配置为0子任务重试次数根据实际情况配置。 机器配置用来标明允许执行任务的机器状态避开那些摇摇欲坠的机器0代表无任何限制。">
<meta name="theme-color" content="#FFFFFF"><meta property="og:title" content="任务管理与在线运维" />
<meta property="og:description" content="前端控制台允许开发者可视化地进行任务增、删、改、查等管理操作,同时也能直观地看到任务的运行数据,包括运行状态、详情和在线日志等。以下为对控制台的详细介绍: 主页 展示了系统整体的概览和集群Worker列表
任务创建 创建需要被调度执行的任务,入口为主页 -&gt; 任务管理 -&gt; 新建任务。
任务名称:名称,便于记忆与搜索,无特殊用途,请尽量简短(占用数据库字段空间)
任务描述:描述,无特殊作用,请尽量简短(占用数据库字段空间)
任务参数任务处理时能够获取到的参数即各个Processor的process方法入参TaskContext对象的jobParams字段进行一次处理器开发就能理解了
定时信息:由下拉框和输入框组成
API -&gt; 不需要填写任何参数(填了也不起作用) CRON -&gt; 填写 CRON 表达式(可以找个在线生成网站生成) 固定频率 -&gt; 填写整数,单位毫秒 固定延迟 -&gt; 填写整数,单位毫秒 执行配置由执行类型单机、广播和MapReduce、处理器类型和处理器参数组成后两项相互关联。
内置Java处理器 -&gt; 填写该处理器的全限定类名eg, com.github.kfcfans.oms.processors.demo.MapReduceProcessorDemo Java容器 -&gt; 填写容器ID#处理器全限定类名eg1#com.github.kfcfans.oms.container.DemoProcessor SHELL -&gt; 填写需要处理的脚本直接复制文件内容或脚本下载连接http://xxx PYTHON -&gt; 填写完整的python脚本或下载连接http://xxx 运行配置
最大实例数:该任务同时执行的数量(任务和实例就像是类和对象的关系,任务被调度执行后被称为实例) 单机线程并发数该实例执行过程中每个Worker使用的线程数量MapReduce任务生效其余无论填什么都只会使用1个线程或3个线程&hellip; 运行时间限制限定任务的最大运行时间超时则视为失败单位毫秒0代表不限制超时时间。 重试配置:
任务重试次数实例级别失败了整个任务实例重试会更换TaskTracker本次任务实例的Master节点代价较大大型Map/MapReduce慎用。 子任务重试次数Task级别每个子Task失败后单独重试会更换ProcessorTracker本次任务实际执行的Worker节点代价较小推荐使用。 注对于单机任务来说假如任务重试次数和子任务重试次数都配置了1且都执行失败实际执行次数会变成4次推荐任务实例重试配置为0子任务重试次数根据实际情况配置。 机器配置用来标明允许执行任务的机器状态避开那些摇摇欲坠的机器0代表无任何限制。" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://kfcfans.gitee.io/ohmyscheduler/docs/startup/4-console-guide/" />
<title>任务管理与在线运维 | OhMyScheduler</title>
<link rel="manifest" href="/ohmyscheduler/manifest.json">
<link rel="icon" href="/ohmyscheduler/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="/ohmyscheduler/book.min.e161f1fe2b283b6a43c29a52fde96e2387fade573e78efa6701d44c8499da76b.css" integrity="sha256-4WHx/isoO2pDwppS/eluI4f63lc&#43;eO&#43;mcB1EyEmdp2s=">
<script defer src="/ohmyscheduler/en.search.min.e2f9b2f3cf3fad006da31fc1558075ea0493c82e60c3b707d1745af9a528b273.js" integrity="sha256-4vmy888/rQBtox/BVYB16gSTyC5gw7cH0XRa&#43;aUosnM="></script>
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
</head>
<body dir=>
<input type="checkbox" class="hidden" id="menu-control" />
<main class="container flex">
<aside class="book-menu">
<nav>
<h2 class="book-brand">
<a href="/ohmyscheduler"><span>OhMyScheduler</span>
</a>
</h2>
<div class="book-search">
<input type="text" id="book-search-input" placeholder="Search" aria-label="Search" maxlength="64" data-hotkeys="s/" />
<div class="book-search-spinner hidden"></div>
<ul id="book-search-results"></ul>
</div>
<ul>
<li>
<span>快速开始</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/startup/1-server-startup/" class="">调度中心Server部署</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/2-worker-startup/" class="">执行器Worker初始化</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/3-processor-develop/" class="">处理器开发</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/4-console-guide/" class="active">任务管理与在线运维</a>
</li>
</ul>
</li>
<li>
<span>高级特性</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/super/container/" class="">容器</a>
</li>
<li>
<a href="/ohmyscheduler/docs/super/openapi/" class="">OpenAPI</a>
</li>
</ul>
</li>
<li>
<span>更新日志</span>
<ul>
</ul>
</li>
</ul>
</nav>
<script>(function(){var menu=document.querySelector("aside.book-menu nav");addEventListener("beforeunload",function(event){localStorage.setItem("menu.scrollTop",menu.scrollTop);});menu.scrollTop=localStorage.getItem("menu.scrollTop");})();</script>
</aside>
<div class="book-page">
<header class="book-header">
<div class="flex align-center justify-between">
<label for="menu-control">
<img src="/ohmyscheduler/svg/menu.svg" class="book-icon" alt="Menu" />
</label>
<strong>任务管理与在线运维</strong>
<label for="toc-control">
<img src="/ohmyscheduler/svg/toc.svg" class="book-icon" alt="Table of Contents" />
</label>
</div>
<input type="checkbox" class="hidden" id="toc-control" />
<aside class="hidden clearfix">
<nav id="TableOfContents">
<ul>
<li><a href="#主页">主页</a></li>
<li><a href="#任务创建">任务创建</a></li>
<li><a href="#任务管理">任务管理</a></li>
<li><a href="#运行状态">运行状态</a></li>
<li><a href="#在线日志">在线日志</a></li>
</ul>
</nav>
</aside>
</header>
<article class="markdown"><blockquote class="book-hint info">
前端控制台允许开发者可视化地进行任务增、删、改、查等管理操作,同时也能直观地看到任务的运行数据,包括运行状态、详情和在线日志等。以下为对控制台的详细介绍:
</blockquote>
<h2 id="主页">主页</h2>
<p>展示了系统整体的概览和集群Worker列表。</p>
<p><img src="/ohmyscheduler/oms-console-main.png" alt="main" /></p>
<h2 id="任务创建">任务创建</h2>
<p>创建需要被调度执行的任务,入口为<strong>主页 -&gt; 任务管理 -&gt; 新建任务</strong></p>
<p><img src="/ohmyscheduler/oms-console-jobCreator.png" alt="jobcreator" /></p>
<ul>
<li>
<p>任务名称:名称,便于记忆与搜索,无特殊用途,请尽量简短(占用数据库字段空间)</p>
</li>
<li>
<p>任务描述:描述,无特殊作用,请尽量简短(占用数据库字段空间)</p>
</li>
<li>
<p>任务参数任务处理时能够获取到的参数即各个Processor的process方法入参<code>TaskContext</code>对象的jobParams字段进行一次处理器开发就能理解了</p>
</li>
<li>
<p>定时信息:由下拉框和输入框组成</p>
<ul>
<li>API -&gt; 不需要填写任何参数(填了也不起作用)</li>
<li>CRON -&gt; 填写 CRON 表达式(可以找个<a href="https://www.bejson.com/othertools/cron/">在线生成网站生成</a></li>
<li>固定频率 -&gt; 填写整数,单位毫秒</li>
<li>固定延迟 -&gt; 填写整数,单位毫秒</li>
</ul>
</li>
<li>
<p>执行配置由执行类型单机、广播和MapReduce、处理器类型和处理器参数组成后两项相互关联。</p>
<ul>
<li>内置Java处理器 -&gt; 填写该处理器的全限定类名eg, <code>com.github.kfcfans.oms.processors.demo.MapReduceProcessorDemo</code></li>
<li>Java容器 -&gt; 填写<strong>容器ID#处理器全限定类名</strong>eg<code>1#com.github.kfcfans.oms.container.DemoProcessor</code></li>
<li>SHELL -&gt; 填写需要处理的脚本直接复制文件内容或脚本下载连接http://xxx</li>
<li>PYTHON -&gt; 填写完整的python脚本或下载连接http://xxx</li>
</ul>
</li>
<li>
<p>运行配置</p>
<ul>
<li>最大实例数:该任务同时执行的数量(任务和实例就像是类和对象的关系,任务被调度执行后被称为实例)</li>
<li>单机线程并发数该实例执行过程中每个Worker使用的线程数量MapReduce任务生效其余无论填什么都只会使用1个线程或3个线程&hellip;</li>
<li>运行时间限制:限定任务的最大运行时间,超时则视为失败,单位<strong>毫秒</strong>0代表不限制超时时间。</li>
</ul>
</li>
<li>
<p>重试配置:</p>
<ul>
<li>任务重试次数实例级别失败了整个任务实例重试会更换TaskTracker本次任务实例的Master节点代价较大大型Map/MapReduce慎用。</li>
<li>子任务重试次数Task级别每个子Task失败后单独重试会更换ProcessorTracker本次任务实际执行的Worker节点代价较小推荐使用。</li>
<li>对于单机任务来说假如任务重试次数和子任务重试次数都配置了1且都执行失败实际执行次数会变成4次推荐任务实例重试配置为0子任务重试次数根据实际情况配置。</li>
</ul>
</li>
<li>
<p>机器配置用来标明允许执行任务的机器状态避开那些摇摇欲坠的机器0代表无任何限制。</p>
<ul>
<li>最低CPU核心数填写浮点数CPU可用核心数小于该值的Worker将不会执行该任务。</li>
<li>最低内存GB填写浮点数可用内存小于该值的Worker将不会执行该任务。</li>
<li>最低磁盘GB填写浮点数可用磁盘空间小于该值的Worker将不会执行该任务。</li>
</ul>
</li>
<li>
<p>集群配置</p>
<ul>
<li>执行机器地址指定集群中的某几台机器执行任务debug的好帮手多值英文逗号分割<code>192.168.1.1:27777,192.168.1.2:27777</code></li>
<li>最大执行机器数量:限定调动执行的机器数量</li>
</ul>
</li>
<li>
<p>报警配置:选择任务执行失败后报警通知的对象,需要事先录入。</p>
</li>
</ul>
<h2 id="任务管理">任务管理</h2>
<p>直观地展示当前系统所管理的所有任务信息,并提供相应的运维方法。</p>
<p><img src="/ohmyscheduler/oms-console-jobManager.png" alt="jobManager" /></p>
<h2 id="运行状态">运行状态</h2>
<p>直观地展示当前系统中运行任务实例的状态,点击详情即可获取详细的信息,点击日志可以查看通过<code>omsLogger</code>上报的日志,点击停止则可以强制终止该任务。</p>
<p><img src="/ohmyscheduler/oms-console-runningStatus.png" alt="status" /></p>
<h2 id="在线日志">在线日志</h2>
<p>在线查看Worker执行过程中上报的日志极大降低debug成本提升开发效率</p>
<p><img src="/ohmyscheduler/oms-console-onlineLog.png" alt="在线日志" /></p>
</article>
<footer class="book-footer">
<div class="flex flex-wrap justify-between">
</div>
</footer>
<div class="book-comments">
</div>
<label for="menu-control" class="hidden book-menu-overlay"></label>
</div>
<aside class="book-toc">
<nav id="TableOfContents">
<ul>
<li><a href="#主页">主页</a></li>
<li><a href="#任务创建">任务创建</a></li>
<li><a href="#任务管理">任务管理</a></li>
<li><a href="#运行状态">运行状态</a></li>
<li><a href="#在线日志">在线日志</a></li>
</ul>
</nav>
</aside>
</main>
</body>
</html>

View File

@ -0,0 +1,298 @@
<!DOCTYPE html>
<html lang="en" dir=>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="theme-color" content="#FFFFFF"><meta property="og:title" content="快速开始" />
<meta property="og:description" content="" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://kfcfans.gitee.io/ohmyscheduler/docs/startup/" />
<title>快速开始 | OhMyScheduler</title>
<link rel="manifest" href="/ohmyscheduler/manifest.json">
<link rel="icon" href="/ohmyscheduler/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="/ohmyscheduler/book.min.e161f1fe2b283b6a43c29a52fde96e2387fade573e78efa6701d44c8499da76b.css" integrity="sha256-4WHx/isoO2pDwppS/eluI4f63lc&#43;eO&#43;mcB1EyEmdp2s=">
<script defer src="/ohmyscheduler/en.search.min.e2f9b2f3cf3fad006da31fc1558075ea0493c82e60c3b707d1745af9a528b273.js" integrity="sha256-4vmy888/rQBtox/BVYB16gSTyC5gw7cH0XRa&#43;aUosnM="></script>
<link rel="alternate" type="application/rss+xml" href="https://kfcfans.gitee.io/ohmyscheduler/docs/startup/index.xml" title="OhMyScheduler" />
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
</head>
<body dir=>
<input type="checkbox" class="hidden" id="menu-control" />
<main class="container flex">
<aside class="book-menu">
<nav>
<h2 class="book-brand">
<a href="/ohmyscheduler"><span>OhMyScheduler</span>
</a>
</h2>
<div class="book-search">
<input type="text" id="book-search-input" placeholder="Search" aria-label="Search" maxlength="64" data-hotkeys="s/" />
<div class="book-search-spinner hidden"></div>
<ul id="book-search-results"></ul>
</div>
<ul>
<li>
<span>快速开始</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/startup/1-server-startup/" class="">调度中心Server部署</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/2-worker-startup/" class="">执行器Worker初始化</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/3-processor-develop/" class="">处理器开发</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/4-console-guide/" class="">任务管理与在线运维</a>
</li>
</ul>
</li>
<li>
<span>高级特性</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/super/container/" class="">容器</a>
</li>
<li>
<a href="/ohmyscheduler/docs/super/openapi/" class="">OpenAPI</a>
</li>
</ul>
</li>
<li>
<span>更新日志</span>
<ul>
</ul>
</li>
</ul>
</nav>
<script>(function(){var menu=document.querySelector("aside.book-menu nav");addEventListener("beforeunload",function(event){localStorage.setItem("menu.scrollTop",menu.scrollTop);});menu.scrollTop=localStorage.getItem("menu.scrollTop");})();</script>
</aside>
<div class="book-page">
<header class="book-header">
<div class="flex align-center justify-between">
<label for="menu-control">
<img src="/ohmyscheduler/svg/menu.svg" class="book-icon" alt="Menu" />
</label>
<strong>快速开始</strong>
<label for="toc-control">
<img src="/ohmyscheduler/svg/toc.svg" class="book-icon" alt="Table of Contents" />
</label>
</div>
<input type="checkbox" class="hidden" id="toc-control" />
<aside class="hidden clearfix">
<nav id="TableOfContents"></nav>
</aside>
</header>
<article class="markdown"></article>
<footer class="book-footer">
<div class="flex flex-wrap justify-between">
</div>
</footer>
<label for="menu-control" class="hidden book-menu-overlay"></label>
</div>
<aside class="book-toc">
<nav id="TableOfContents"></nav>
</aside>
</main>
</body>
</html>

View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>快速开始 on OhMyScheduler</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/</link>
<description>Recent content in 快速开始 on OhMyScheduler</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<atom:link href="https://kfcfans.gitee.io/ohmyscheduler/docs/startup/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>调度中心Server部署</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/1-server-startup/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/1-server-startup/</guid>
<description>环境要求 Open JDK 8+
Apache Maven 3+
任意 Spring Data Jpa 支持的关系型数据库MySQL/Oracle/MS SQLServer&amp;hellip;
MongoDB可选任意支持GridFS的mongoDB版本4.2.6测试通过,其余未经测试,仅从理论角度分析可用),缺失该组件的情况下将无法使用在线日志、容器部署等扩展功能
初始化关系数据库 调度服务器oh-my-scheduler-server的持久化层基于Spring Boot Jpa实现对于能够直连数据库的应用开发者仅需完成数据库的创建即运行SQLCREATE database if NOT EXISTS oms-product default character set utf8mb4 collate utf8mb4_unicode_ci;`
OhMyScheduler支持环境隔离提供日常daily、预发pre和线上product三套环境请根据使用的环境分别部署对应的数据库oms-daily、oms-pre和oms-product。 调度服务器属于时间敏感应用强烈建议检查当前数据库所使用的时区信息show variables like &amp;quot;%time_zone%&amp;quot;;务必确保time_zone代表的时区与JDBC URL中serverTimezone字段代表的时区一致 手动建表表SQL文件下载地址 部署调度服务器—源码编译 调度服务器oh-my-scheduler-server支持任意的水平扩展即多实例集群部署仅需要在同一个局域网内启动新的服务器实例性能强劲无上限
调度服务器oh-my-scheduler-server为了支持环境隔离分别采用了日常application-daily.properties、预发application-pre.properties和线上application-product.properties三套配置文件请根据实际需求进行修改以下为配置文件详解。
配置项 含义 可选 server.port SpringBoot配置HTTP端口号默认7700 否 oms.</description>
</item>
<item>
<title>执行器Worker初始化</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/2-worker-startup/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/2-worker-startup/</guid>
<description>基于宿主应用的执行器初始化 宿主应用即原有的业务应用,假如需要调度执行的任务与当前业务有较为紧密的联系,建议采取该方式。
首先添加相关的jar包依赖最新依赖版本请参考maven中央仓库推荐地址&amp;amp;备用地址
&amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;com.github.kfcfans&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;oh-my-scheduler-worker&amp;lt;/artifactId&amp;gt; &amp;lt;version&amp;gt;1.2.0&amp;lt;/version&amp;gt; &amp;lt;/dependency&amp;gt; 其次填写执行器客户端配置文件OhMyConfig各参数说明如下表所示
属性名称 含义 默认值 appName 宿主应用名称,需要提前在控制台完成注册 无,必填项,否则启动报错 port Worker工作端口 27777 serverAddress 调度中心oh-my-scheduler-server地址列表 无,必填项,否则启动报错 storeStrategy 本地存储策略,枚举值磁盘/内存大型MapReduce等会产生大量Task的任务推荐使用磁盘降低内存压力否则建议使用内存加速计算 StoreStrategy.DISK磁盘 maxResultLength 每个Task返回结果的默认长度超长将被截断。过长可能导致网络拥塞 8096 enableTestMode 是否启用测试模式启用后无需Server也能顺利启动OhMyScheduler-Worker用于处理器本地的单元测试 false 最后,初始化客户端,完成执行器的启动,代码示例如下:
@Configuration public class OhMySchedulerConfig { @Bean public OhMyWorker initOMS() throws Exception { // 服务器HTTP地址端口号为 server.port而不是 ActorSystem port List&amp;lt;String&amp;gt; serverAddress = Lists.</description>
</item>
<item>
<title>处理器开发</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/3-processor-develop/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/3-processor-develop/</guid>
<description>处理器概述 OhMyScheduler当前支持Shell、Python等脚本处理器和Java处理器。脚本处理器只需要开发者完成脚本的编写xxx.sh / xxx.py在控制台填入脚本内容即可本章不再赘述。本章将重点阐述Java处理器开发方法与使用技巧。
Java处理器可根据代码所处位置划分为内置Java处理器和容器Java处理器前者直接集成在宿主应用也就是接入本系统的业务应用一般用来处理业务需求后者可以在一个独立的轻量级的Java工程中开发通过容器技术详见容器章节被worker集群热加载提供Java的“脚本能力”一般用于处理灵活多变的需求。 Java处理器可根据对象创建者划分为SpringBean处理器和普通Java对象处理器前者由Spring IOC容器完成处理器的创建和初始化后者则有OhMyScheduler维护其状态。如果宿主应用支持Spring强烈建议使用SpringBean处理器开发者仅需要将Processor注册进Spring IOC容器一个@Component注解或一句bean配置。 Java处理器可根据功能划分为单机处理器、广播处理器、Map处理器和MapReduce处理器。 单机处理器BasicProcessor对应了单机任务即某个任务的某次运行只会有某一台机器的某一个线程参与运算。 广播处理器BroadcastProcessor对应了广播任务即某个任务的某次运行会调动集群内所有机器参与运算。 Map处理器MapProcessor对应了Map任务即某个任务在运行过程中允许产生子任务并分发到其他机器进行运算。 MapReduce处理器MapReduceProcessor对应了MapReduce任务在Map任务的基础上增加了所有任务结束后的汇总统计。 核心方法process 任意Java处理器都需要实现处理的核心方法其接口签名如下
ProcessResult process(TaskContext context) throws Exception; 方法入参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造成巨大的压力 方法的返回值为ProcessResult代表了本次Task执行的结果包含success和msg两个属性分别用于传递Task是否执行成功和Task需要返回的信息。</description>
</item>
<item>
<title>任务管理与在线运维</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/4-console-guide/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/4-console-guide/</guid>
<description>前端控制台允许开发者可视化地进行任务增、删、改、查等管理操作,同时也能直观地看到任务的运行数据,包括运行状态、详情和在线日志等。以下为对控制台的详细介绍: 主页 展示了系统整体的概览和集群Worker列表。
任务创建 创建需要被调度执行的任务,入口为主页 -&amp;gt; 任务管理 -&amp;gt; 新建任务。
任务名称:名称,便于记忆与搜索,无特殊用途,请尽量简短(占用数据库字段空间)
任务描述:描述,无特殊作用,请尽量简短(占用数据库字段空间)
任务参数任务处理时能够获取到的参数即各个Processor的process方法入参TaskContext对象的jobParams字段进行一次处理器开发就能理解了
定时信息:由下拉框和输入框组成
API -&amp;gt; 不需要填写任何参数(填了也不起作用) CRON -&amp;gt; 填写 CRON 表达式(可以找个在线生成网站生成) 固定频率 -&amp;gt; 填写整数,单位毫秒 固定延迟 -&amp;gt; 填写整数,单位毫秒 执行配置由执行类型单机、广播和MapReduce、处理器类型和处理器参数组成后两项相互关联。
内置Java处理器 -&amp;gt; 填写该处理器的全限定类名eg, com.github.kfcfans.oms.processors.demo.MapReduceProcessorDemo Java容器 -&amp;gt; 填写容器ID#处理器全限定类名eg1#com.github.kfcfans.oms.container.DemoProcessor SHELL -&amp;gt; 填写需要处理的脚本直接复制文件内容或脚本下载连接http://xxx PYTHON -&amp;gt; 填写完整的python脚本或下载连接http://xxx 运行配置
最大实例数:该任务同时执行的数量(任务和实例就像是类和对象的关系,任务被调度执行后被称为实例) 单机线程并发数该实例执行过程中每个Worker使用的线程数量MapReduce任务生效其余无论填什么都只会使用1个线程或3个线程&amp;hellip; 运行时间限制限定任务的最大运行时间超时则视为失败单位毫秒0代表不限制超时时间。 重试配置:
任务重试次数实例级别失败了整个任务实例重试会更换TaskTracker本次任务实例的Master节点代价较大大型Map/MapReduce慎用。 子任务重试次数Task级别每个子Task失败后单独重试会更换ProcessorTracker本次任务实际执行的Worker节点代价较小推荐使用。 注对于单机任务来说假如任务重试次数和子任务重试次数都配置了1且都执行失败实际执行次数会变成4次推荐任务实例重试配置为0子任务重试次数根据实际情况配置。 机器配置用来标明允许执行任务的机器状态避开那些摇摇欲坠的机器0代表无任何限制。</description>
</item>
</channel>
</rss>

View File

@ -0,0 +1,395 @@
<!DOCTYPE html>
<html lang="en" dir=>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="什么是容器? 介绍 OhMyScheduler的容器技术允许开发者开发独立于Worker项目之外Java处理器简单来说就是以Maven工程项目的维度去组织一堆Java文件开发者开发的众多脚本处理器进而兼具开发效率和可维护性
用途举例 比如突然出现了某个数据库数据清理任务与主业务无关写进原本的项目工程中不太优雅这时候就可以单独创建一个用于数据操作的容器在里面完成处理器的开发通过OhMyScheduler的容器部署技术在Worker集群上被加载执行。 比如常见的日志清理啊机器状态上报啊对于广大Java程序员来说也许并不是很会写shell脚本此时也可以借用agent&#43;容器技术利用Java完成各项原本需要通过脚本进行的操作。 (感觉例子举的都不是很好&hellip;这个东西嘛,只可意会不可言传,大家努力理解一下吧~超好用哦~)
生成容器模版 为了方便开发者使用,最新版本的前端页面已经支持容器工程模版的自动生成,开发者仅需要填入相关信息即可下载容器模版开始开发。 Group对应Maven的&lt;groupId&gt;标签,一般填入倒写的公司域名。 Artifact对于Maven的&lt;artifactId&gt;标签,填入代表该容器的唯一标示。 Name对应Maven的&lt;name&gt;标签,填入该容器名称。 Package Name包名代表了的容器工程内部所使用的包名警告包名一旦生成后请勿更改否则会导致运行时容器加载错误当然如有必须修改包名的需求可以尝试替换/resource下以oms-worker-container开头的所有文件相关的值。 Java Version容器工程的Java版本请务必与容器目标部署Worker平台的Java版本保持一致。 开发容器工程 完成容器模版创建后下载解压会得到如下结构的Java工程
oms-template-origin // 工程名称,可以自由更改 ├── pom.xml └── src ├── main │ ├── java │ │ └── cn │ │ └── edu │ │ └── zju │ │ └── tjq │ │ └── container │ │ └── samples // 所有处理器代码必须位于该目录下,其余类随意 │ └── resources // 严禁随意更改以下两个配置文件(允许添加,不允许更改现有内容) │ ├── oms-worker-container-spring-context.xml │ └── oms-worker-container.">
<meta name="theme-color" content="#FFFFFF"><meta property="og:title" content="容器" />
<meta property="og:description" content="什么是容器? 介绍 OhMyScheduler的容器技术允许开发者开发独立于Worker项目之外Java处理器简单来说就是以Maven工程项目的维度去组织一堆Java文件开发者开发的众多脚本处理器进而兼具开发效率和可维护性
用途举例 比如突然出现了某个数据库数据清理任务与主业务无关写进原本的项目工程中不太优雅这时候就可以单独创建一个用于数据操作的容器在里面完成处理器的开发通过OhMyScheduler的容器部署技术在Worker集群上被加载执行。 比如常见的日志清理啊机器状态上报啊对于广大Java程序员来说也许并不是很会写shell脚本此时也可以借用agent&#43;容器技术利用Java完成各项原本需要通过脚本进行的操作。 (感觉例子举的都不是很好&hellip;这个东西嘛,只可意会不可言传,大家努力理解一下吧~超好用哦~)
生成容器模版 为了方便开发者使用,最新版本的前端页面已经支持容器工程模版的自动生成,开发者仅需要填入相关信息即可下载容器模版开始开发。 Group对应Maven的&lt;groupId&gt;标签,一般填入倒写的公司域名。 Artifact对于Maven的&lt;artifactId&gt;标签,填入代表该容器的唯一标示。 Name对应Maven的&lt;name&gt;标签,填入该容器名称。 Package Name包名代表了的容器工程内部所使用的包名警告包名一旦生成后请勿更改否则会导致运行时容器加载错误当然如有必须修改包名的需求可以尝试替换/resource下以oms-worker-container开头的所有文件相关的值。 Java Version容器工程的Java版本请务必与容器目标部署Worker平台的Java版本保持一致。 开发容器工程 完成容器模版创建后下载解压会得到如下结构的Java工程
oms-template-origin // 工程名称,可以自由更改 ├── pom.xml └── src ├── main │ ├── java │ │ └── cn │ │ └── edu │ │ └── zju │ │ └── tjq │ │ └── container │ │ └── samples // 所有处理器代码必须位于该目录下,其余类随意 │ └── resources // 严禁随意更改以下两个配置文件(允许添加,不允许更改现有内容) │ ├── oms-worker-container-spring-context.xml │ └── oms-worker-container." />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://kfcfans.gitee.io/ohmyscheduler/docs/super/container/" />
<title>容器 | OhMyScheduler</title>
<link rel="manifest" href="/ohmyscheduler/manifest.json">
<link rel="icon" href="/ohmyscheduler/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="/ohmyscheduler/book.min.e161f1fe2b283b6a43c29a52fde96e2387fade573e78efa6701d44c8499da76b.css" integrity="sha256-4WHx/isoO2pDwppS/eluI4f63lc&#43;eO&#43;mcB1EyEmdp2s=">
<script defer src="/ohmyscheduler/en.search.min.e2f9b2f3cf3fad006da31fc1558075ea0493c82e60c3b707d1745af9a528b273.js" integrity="sha256-4vmy888/rQBtox/BVYB16gSTyC5gw7cH0XRa&#43;aUosnM="></script>
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
</head>
<body dir=>
<input type="checkbox" class="hidden" id="menu-control" />
<main class="container flex">
<aside class="book-menu">
<nav>
<h2 class="book-brand">
<a href="/ohmyscheduler"><span>OhMyScheduler</span>
</a>
</h2>
<div class="book-search">
<input type="text" id="book-search-input" placeholder="Search" aria-label="Search" maxlength="64" data-hotkeys="s/" />
<div class="book-search-spinner hidden"></div>
<ul id="book-search-results"></ul>
</div>
<ul>
<li>
<span>快速开始</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/startup/1-server-startup/" class="">调度中心Server部署</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/2-worker-startup/" class="">执行器Worker初始化</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/3-processor-develop/" class="">处理器开发</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/4-console-guide/" class="">任务管理与在线运维</a>
</li>
</ul>
</li>
<li>
<span>高级特性</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/super/container/" class="active">容器</a>
</li>
<li>
<a href="/ohmyscheduler/docs/super/openapi/" class="">OpenAPI</a>
</li>
</ul>
</li>
<li>
<span>更新日志</span>
<ul>
</ul>
</li>
</ul>
</nav>
<script>(function(){var menu=document.querySelector("aside.book-menu nav");addEventListener("beforeunload",function(event){localStorage.setItem("menu.scrollTop",menu.scrollTop);});menu.scrollTop=localStorage.getItem("menu.scrollTop");})();</script>
</aside>
<div class="book-page">
<header class="book-header">
<div class="flex align-center justify-between">
<label for="menu-control">
<img src="/ohmyscheduler/svg/menu.svg" class="book-icon" alt="Menu" />
</label>
<strong>容器</strong>
<label for="toc-control">
<img src="/ohmyscheduler/svg/toc.svg" class="book-icon" alt="Table of Contents" />
</label>
</div>
<input type="checkbox" class="hidden" id="toc-control" />
<aside class="hidden clearfix">
<nav id="TableOfContents">
<ul>
<li><a href="#什么是容器">什么是容器?</a>
<ul>
<li><a href="#介绍">介绍</a></li>
<li><a href="#用途举例">用途举例</a></li>
</ul>
</li>
<li><a href="#生成容器模版">生成容器模版</a></li>
<li><a href="#开发容器工程">开发容器工程</a></li>
<li><a href="#创建容器">创建容器</a></li>
<li><a href="#部署容器">部署容器</a></li>
</ul>
</nav>
</aside>
</header>
<article class="markdown"><h2 id="什么是容器">什么是容器?</h2>
<h3 id="介绍">介绍</h3>
<p>OhMyScheduler的容器技术允许开发者<strong>开发独立于Worker项目之外Java处理器</strong>简单来说就是以Maven工程项目的维度去组织一堆Java文件开发者开发的众多脚本处理器进而兼具开发效率和可维护性。</p>
<h3 id="用途举例">用途举例</h3>
<ul>
<li>比如突然出现了某个数据库数据清理任务与主业务无关写进原本的项目工程中不太优雅这时候就可以单独创建一个用于数据操作的容器在里面完成处理器的开发通过OhMyScheduler的容器部署技术在Worker集群上被加载执行。</li>
<li>比如常见的日志清理啊机器状态上报啊对于广大Java程序员来说也许并不是很会写shell脚本此时也可以借用<strong>agent+容器</strong>技术利用Java完成各项原本需要通过脚本进行的操作。</li>
</ul>
<p>(感觉例子举的都不是很好&hellip;这个东西嘛,只可意会不可言传,大家努力理解一下吧~超好用哦~)</p>
<h2 id="生成容器模版">生成容器模版</h2>
<blockquote class="book-hint info">
为了方便开发者使用,最新版本的前端页面已经支持容器工程模版的自动生成,开发者仅需要填入相关信息即可下载容器模版开始开发。
</blockquote>
<p><img src="/ohmyscheduler/oms-console-container-template.png" alt="template" /></p>
<ul>
<li>Group对应Maven的<code>&lt;groupId&gt;</code>标签,一般填入倒写的公司域名。</li>
<li>Artifact对于Maven的<code>&lt;artifactId&gt;</code>标签,填入代表该容器的唯一标示。</li>
<li>Name对应Maven的<code>&lt;name&gt;</code>标签,填入该容器名称。</li>
<li>Package Name包名代表了的容器工程内部所使用的包名<strong>警告:包名一旦生成后,请勿更改!否则会导致运行时容器加载错误</strong>(当然,如有必须修改包名的需求,可以尝试替换<code>/resource</code>下以<code>oms-worker-container</code>开头的所有文件相关的值)。</li>
<li>Java Version容器工程的Java版本<strong>请务必与容器目标部署Worker平台的Java版本保持一致</strong></li>
</ul>
<h2 id="开发容器工程">开发容器工程</h2>
<p>完成容器模版创建后下载解压会得到如下结构的Java工程</p>
<pre><code>oms-template-origin // 工程名称,可以自由更改
├── pom.xml
└── src
├── main
│   ├── java
│   │   └── cn
│   │   └── edu
│   │   └── zju
│   │   └── tjq
│   │   └── container
│   │   └── samples // 所有处理器代码必须位于该目录下,其余类随意
│   └── resources // 严禁随意更改以下两个配置文件(允许添加,不允许更改现有内容)
│   ├── oms-worker-container-spring-context.xml
│   └── oms-worker-container.properties
└── test
└── java
</code></pre><p>之后便可以愉快地在<strong>packageName</strong>下编写处理器代码啦~</p>
<p>需要示例代码?<a href="https://gitee.com/KFCFans/OhMyScheduler-Container-Template">客官这边请~</a></p>
<h2 id="创建容器">创建容器</h2>
<p>目前OhMyScheduler支持使用<strong>Git代码库</strong><strong>FatJar</strong>来创建容器。创建路径:<strong>容器运维 -&gt; 容器管理 -&gt; 新建容器</strong></p>
<blockquote class="book-hint warning">
当使用<strong>Git代码库</strong>创建容器时OhMyScheduler-Server需要完成代码库的下载、编译、构建和上传<strong>因此需要server运行环境包含可用的Git和Maven环境包括私服的访问权限</strong>
</blockquote>
<p>下图为使用<strong>Git代码库</strong>创建容器的示例,需要填入容器名称和代码库信息等参数:</p>
<p><img src="/ohmyscheduler/oms-console-container-newgit.png" alt="new-git-container" /></p>
<p>下图为使用<strong>FatJar</strong>创建容器的示例,需要上传可用的<strong>FatJar</strong>FatJar值包含了所有依赖的Jar文件</p>
<p><img src="/ohmyscheduler/oms-console-container-newfatjar.png" alt="new-git-container" /></p>
<h2 id="部署容器">部署容器</h2>
<blockquote class="book-hint info">
完成容器创建后,便可在容器管理界面查看已创建的容器,点击<strong>部署</strong>,可以看到详细的部署信息。
</blockquote>
<p><img src="/ohmyscheduler/oms-console-container-deploy.png" alt="new-git-container" /></p>
<blockquote class="book-hint info">
部署完成后,可以点击<strong>机器列表</strong>查看已部署该容器的机器信息。
</blockquote>
</article>
<footer class="book-footer">
<div class="flex flex-wrap justify-between">
</div>
</footer>
<div class="book-comments">
</div>
<label for="menu-control" class="hidden book-menu-overlay"></label>
</div>
<aside class="book-toc">
<nav id="TableOfContents">
<ul>
<li><a href="#什么是容器">什么是容器?</a>
<ul>
<li><a href="#介绍">介绍</a></li>
<li><a href="#用途举例">用途举例</a></li>
</ul>
</li>
<li><a href="#生成容器模版">生成容器模版</a></li>
<li><a href="#开发容器工程">开发容器工程</a></li>
<li><a href="#创建容器">创建容器</a></li>
<li><a href="#部署容器">部署容器</a></li>
</ul>
</nav>
</aside>
</main>
</body>
</html>

View File

@ -0,0 +1,298 @@
<!DOCTYPE html>
<html lang="en" dir=>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="theme-color" content="#FFFFFF"><meta property="og:title" content="高级特性" />
<meta property="og:description" content="" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://kfcfans.gitee.io/ohmyscheduler/docs/super/" />
<title>高级特性 | OhMyScheduler</title>
<link rel="manifest" href="/ohmyscheduler/manifest.json">
<link rel="icon" href="/ohmyscheduler/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="/ohmyscheduler/book.min.e161f1fe2b283b6a43c29a52fde96e2387fade573e78efa6701d44c8499da76b.css" integrity="sha256-4WHx/isoO2pDwppS/eluI4f63lc&#43;eO&#43;mcB1EyEmdp2s=">
<script defer src="/ohmyscheduler/en.search.min.e2f9b2f3cf3fad006da31fc1558075ea0493c82e60c3b707d1745af9a528b273.js" integrity="sha256-4vmy888/rQBtox/BVYB16gSTyC5gw7cH0XRa&#43;aUosnM="></script>
<link rel="alternate" type="application/rss+xml" href="https://kfcfans.gitee.io/ohmyscheduler/docs/super/index.xml" title="OhMyScheduler" />
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
</head>
<body dir=>
<input type="checkbox" class="hidden" id="menu-control" />
<main class="container flex">
<aside class="book-menu">
<nav>
<h2 class="book-brand">
<a href="/ohmyscheduler"><span>OhMyScheduler</span>
</a>
</h2>
<div class="book-search">
<input type="text" id="book-search-input" placeholder="Search" aria-label="Search" maxlength="64" data-hotkeys="s/" />
<div class="book-search-spinner hidden"></div>
<ul id="book-search-results"></ul>
</div>
<ul>
<li>
<span>快速开始</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/startup/1-server-startup/" class="">调度中心Server部署</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/2-worker-startup/" class="">执行器Worker初始化</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/3-processor-develop/" class="">处理器开发</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/4-console-guide/" class="">任务管理与在线运维</a>
</li>
</ul>
</li>
<li>
<span>高级特性</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/super/container/" class="">容器</a>
</li>
<li>
<a href="/ohmyscheduler/docs/super/openapi/" class="">OpenAPI</a>
</li>
</ul>
</li>
<li>
<span>更新日志</span>
<ul>
</ul>
</li>
</ul>
</nav>
<script>(function(){var menu=document.querySelector("aside.book-menu nav");addEventListener("beforeunload",function(event){localStorage.setItem("menu.scrollTop",menu.scrollTop);});menu.scrollTop=localStorage.getItem("menu.scrollTop");})();</script>
</aside>
<div class="book-page">
<header class="book-header">
<div class="flex align-center justify-between">
<label for="menu-control">
<img src="/ohmyscheduler/svg/menu.svg" class="book-icon" alt="Menu" />
</label>
<strong>高级特性</strong>
<label for="toc-control">
<img src="/ohmyscheduler/svg/toc.svg" class="book-icon" alt="Table of Contents" />
</label>
</div>
<input type="checkbox" class="hidden" id="toc-control" />
<aside class="hidden clearfix">
<nav id="TableOfContents"></nav>
</aside>
</header>
<article class="markdown"></article>
<footer class="book-footer">
<div class="flex flex-wrap justify-between">
</div>
</footer>
<label for="menu-control" class="hidden book-menu-overlay"></label>
</div>
<aside class="book-toc">
<nav id="TableOfContents"></nav>
</aside>
</main>
</body>
</html>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>高级特性 on OhMyScheduler</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/docs/super/</link>
<description>Recent content in 高级特性 on OhMyScheduler</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<atom:link href="https://kfcfans.gitee.io/ohmyscheduler/docs/super/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>容器</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/docs/super/container/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>https://kfcfans.gitee.io/ohmyscheduler/docs/super/container/</guid>
<description>什么是容器? 介绍 OhMyScheduler的容器技术允许开发者开发独立于Worker项目之外Java处理器简单来说就是以Maven工程项目的维度去组织一堆Java文件开发者开发的众多脚本处理器进而兼具开发效率和可维护性。
用途举例 比如突然出现了某个数据库数据清理任务与主业务无关写进原本的项目工程中不太优雅这时候就可以单独创建一个用于数据操作的容器在里面完成处理器的开发通过OhMyScheduler的容器部署技术在Worker集群上被加载执行。 比如常见的日志清理啊机器状态上报啊对于广大Java程序员来说也许并不是很会写shell脚本此时也可以借用agent+容器技术利用Java完成各项原本需要通过脚本进行的操作。 (感觉例子举的都不是很好&amp;hellip;这个东西嘛,只可意会不可言传,大家努力理解一下吧~超好用哦~)
生成容器模版 为了方便开发者使用,最新版本的前端页面已经支持容器工程模版的自动生成,开发者仅需要填入相关信息即可下载容器模版开始开发。 Group对应Maven的&amp;lt;groupId&amp;gt;标签,一般填入倒写的公司域名。 Artifact对于Maven的&amp;lt;artifactId&amp;gt;标签,填入代表该容器的唯一标示。 Name对应Maven的&amp;lt;name&amp;gt;标签,填入该容器名称。 Package Name包名代表了的容器工程内部所使用的包名警告包名一旦生成后请勿更改否则会导致运行时容器加载错误当然如有必须修改包名的需求可以尝试替换/resource下以oms-worker-container开头的所有文件相关的值。 Java Version容器工程的Java版本请务必与容器目标部署Worker平台的Java版本保持一致。 开发容器工程 完成容器模版创建后下载解压会得到如下结构的Java工程
oms-template-origin // 工程名称,可以自由更改 ├── pom.xml └── src ├── main │ ├── java │ │ └── cn │ │ └── edu │ │ └── zju │ │ └── tjq │ │ └── container │ │ └── samples // 所有处理器代码必须位于该目录下,其余类随意 │ └── resources // 严禁随意更改以下两个配置文件(允许添加,不允许更改现有内容) │ ├── oms-worker-container-spring-context.xml │ └── oms-worker-container.</description>
</item>
<item>
<title>OpenAPI</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/docs/super/openapi/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>https://kfcfans.gitee.io/ohmyscheduler/docs/super/openapi/</guid>
<description>OpenAPI允许开发者通过接口来完成手工的操作让系统整体变得更加灵活。开发者可以基于API便捷地扩展OhMyScheduler原有的功能。 依赖 最新依赖版本请参考Maven中央仓库推荐地址&amp;amp;备用地址。
&amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;com.github.kfcfans&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;oh-my-scheduler-client&amp;lt;/artifactId&amp;gt; &amp;lt;version&amp;gt;1.2.0&amp;lt;/version&amp;gt; &amp;lt;/dependency&amp;gt; 简单示例 // 初始化 client需要server地址和应用名称作为参数 OhMyClient ohMyClient = new OhMyClient(&amp;#34;127.0.0.1:7700&amp;#34;, &amp;#34;oms-test&amp;#34;); // 调用相关的API ohMyClient.stopInstance(1586855173043L) API列表 创建/修改任务 接口签名ResultDTO&amp;lt;Long&amp;gt; saveJob(ClientJobInfo newJobInfo)
入参:任务信息(详细说明见下表,也可以参考前端任务创建各参数的正确填法)
返回值ResultDTO根据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.</description>
</item>
</channel>
</rss>

View File

@ -0,0 +1,492 @@
<!DOCTYPE html>
<html lang="en" dir=>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="OpenAPI允许开发者通过接口来完成手工的操作让系统整体变得更加灵活。开发者可以基于API便捷地扩展OhMyScheduler原有的功能。 依赖 最新依赖版本请参考Maven中央仓库推荐地址&amp;备用地址
&lt;dependency&gt; &lt;groupId&gt;com.github.kfcfans&lt;/groupId&gt; &lt;artifactId&gt;oh-my-scheduler-client&lt;/artifactId&gt; &lt;version&gt;1.2.0&lt;/version&gt; &lt;/dependency&gt; 简单示例 // 初始化 client需要server地址和应用名称作为参数 OhMyClient ohMyClient = new OhMyClient(&#34;127.0.0.1:7700&#34;, &#34;oms-test&#34;); // 调用相关的API ohMyClient.stopInstance(1586855173043L) API列表 创建/修改任务 接口签名ResultDTO&lt;Long&gt; saveJob(ClientJobInfo newJobInfo)
入参:任务信息(详细说明见下表,也可以参考前端任务创建各参数的正确填法)
返回值ResultDTO根据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.">
<meta name="theme-color" content="#FFFFFF"><meta property="og:title" content="OpenAPI" />
<meta property="og:description" content="OpenAPI允许开发者通过接口来完成手工的操作让系统整体变得更加灵活。开发者可以基于API便捷地扩展OhMyScheduler原有的功能。 依赖 最新依赖版本请参考Maven中央仓库推荐地址&amp;备用地址
&lt;dependency&gt; &lt;groupId&gt;com.github.kfcfans&lt;/groupId&gt; &lt;artifactId&gt;oh-my-scheduler-client&lt;/artifactId&gt; &lt;version&gt;1.2.0&lt;/version&gt; &lt;/dependency&gt; 简单示例 // 初始化 client需要server地址和应用名称作为参数 OhMyClient ohMyClient = new OhMyClient(&#34;127.0.0.1:7700&#34;, &#34;oms-test&#34;); // 调用相关的API ohMyClient.stopInstance(1586855173043L) API列表 创建/修改任务 接口签名ResultDTO&lt;Long&gt; saveJob(ClientJobInfo newJobInfo)
入参:任务信息(详细说明见下表,也可以参考前端任务创建各参数的正确填法)
返回值ResultDTO根据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." />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://kfcfans.gitee.io/ohmyscheduler/docs/super/openapi/" />
<title>OpenAPI | OhMyScheduler</title>
<link rel="manifest" href="/ohmyscheduler/manifest.json">
<link rel="icon" href="/ohmyscheduler/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="/ohmyscheduler/book.min.e161f1fe2b283b6a43c29a52fde96e2387fade573e78efa6701d44c8499da76b.css" integrity="sha256-4WHx/isoO2pDwppS/eluI4f63lc&#43;eO&#43;mcB1EyEmdp2s=">
<script defer src="/ohmyscheduler/en.search.min.e2f9b2f3cf3fad006da31fc1558075ea0493c82e60c3b707d1745af9a528b273.js" integrity="sha256-4vmy888/rQBtox/BVYB16gSTyC5gw7cH0XRa&#43;aUosnM="></script>
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
</head>
<body dir=>
<input type="checkbox" class="hidden" id="menu-control" />
<main class="container flex">
<aside class="book-menu">
<nav>
<h2 class="book-brand">
<a href="/ohmyscheduler"><span>OhMyScheduler</span>
</a>
</h2>
<div class="book-search">
<input type="text" id="book-search-input" placeholder="Search" aria-label="Search" maxlength="64" data-hotkeys="s/" />
<div class="book-search-spinner hidden"></div>
<ul id="book-search-results"></ul>
</div>
<ul>
<li>
<span>快速开始</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/startup/1-server-startup/" class="">调度中心Server部署</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/2-worker-startup/" class="">执行器Worker初始化</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/3-processor-develop/" class="">处理器开发</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/4-console-guide/" class="">任务管理与在线运维</a>
</li>
</ul>
</li>
<li>
<span>高级特性</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/super/container/" class="">容器</a>
</li>
<li>
<a href="/ohmyscheduler/docs/super/openapi/" class="active">OpenAPI</a>
</li>
</ul>
</li>
<li>
<span>更新日志</span>
<ul>
</ul>
</li>
</ul>
</nav>
<script>(function(){var menu=document.querySelector("aside.book-menu nav");addEventListener("beforeunload",function(event){localStorage.setItem("menu.scrollTop",menu.scrollTop);});menu.scrollTop=localStorage.getItem("menu.scrollTop");})();</script>
</aside>
<div class="book-page">
<header class="book-header">
<div class="flex align-center justify-between">
<label for="menu-control">
<img src="/ohmyscheduler/svg/menu.svg" class="book-icon" alt="Menu" />
</label>
<strong>OpenAPI</strong>
<label for="toc-control">
<img src="/ohmyscheduler/svg/toc.svg" class="book-icon" alt="Table of Contents" />
</label>
</div>
<input type="checkbox" class="hidden" id="toc-control" />
<aside class="hidden clearfix">
<nav id="TableOfContents">
<ul>
<li><a href="#依赖">依赖</a></li>
<li><a href="#简单示例">简单示例</a></li>
<li><a href="#api列表">API列表</a>
<ul>
<li><a href="#创建修改任务">创建/修改任务</a></li>
<li><a href="#查找任务">查找任务</a></li>
<li><a href="#禁用某个任务">禁用某个任务</a></li>
<li><a href="#启用某个任务">启用某个任务</a></li>
<li><a href="#删除某个任务">删除某个任务</a></li>
<li><a href="#立即运行某个任务">立即运行某个任务</a></li>
<li><a href="#停止某个任务实例">停止某个任务实例</a></li>
<li><a href="#查询某个任务实例">查询某个任务实例</a></li>
<li><a href="#查询某个任务实例的状态">查询某个任务实例的状态</a></li>
</ul>
</li>
</ul>
</nav>
</aside>
</header>
<article class="markdown"><blockquote class="book-hint info">
OpenAPI允许开发者通过接口来完成手工的操作让系统整体变得更加灵活。开发者可以基于API便捷地扩展OhMyScheduler原有的功能。
</blockquote>
<h2 id="依赖">依赖</h2>
<p>最新依赖版本请参考Maven中央仓库<a href="https://search.maven.org/search?q=oh-my-scheduler-client">推荐地址</a>&amp;<a href="https://mvnrepository.com/search?q=com.github.kfcfans">备用地址</a></p>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-xml" data-lang="xml"><span style="color:#f92672">&lt;dependency&gt;</span>
<span style="color:#f92672">&lt;groupId&gt;</span>com.github.kfcfans<span style="color:#f92672">&lt;/groupId&gt;</span>
<span style="color:#f92672">&lt;artifactId&gt;</span>oh-my-scheduler-client<span style="color:#f92672">&lt;/artifactId&gt;</span>
<span style="color:#f92672">&lt;version&gt;</span>1.2.0<span style="color:#f92672">&lt;/version&gt;</span>
<span style="color:#f92672">&lt;/dependency&gt;</span>
</code></pre></div><h2 id="简单示例">简单示例</h2>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text">// 初始化 client需要server地址和应用名称作为参数
OhMyClient ohMyClient = new OhMyClient(&#34;127.0.0.1:7700&#34;, &#34;oms-test&#34;);
// 调用相关的API
ohMyClient.stopInstance(1586855173043L)
</code></pre></div><h2 id="api列表">API列表</h2>
<h3 id="创建修改任务">创建/修改任务</h3>
<p>接口签名:<code>ResultDTO&lt;Long&gt; saveJob(ClientJobInfo newJobInfo)</code></p>
<p>入参:任务信息(详细说明见下表,也可以参考<a href="./ConsoleGuide.md">前端任务创建各参数的正确填法</a></p>
<p>返回值ResultDTO<!-- raw HTML omitted -->根据success判断操作是否成功。若操作成功data字段返回任务ID</p>
<table>
<thead>
<tr>
<th>属性</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>jobId</td>
<td>任务ID可选null代表创建任务否则填写需要修改的任务ID</td>
</tr>
<tr>
<td>jobName</td>
<td>任务名称</td>
</tr>
<tr>
<td>jobDescription</td>
<td>任务描述</td>
</tr>
<tr>
<td>jobParams</td>
<td>任务参数Processor#process方法入参<code>TaskContext</code>对象的jobParams字段</td>
</tr>
<tr>
<td>timeExpressionType</td>
<td>时间表达式类型,枚举值</td>
</tr>
<tr>
<td>timeExpression</td>
<td>时间表达式填写类型由timeExpressionType决定比如CRON需要填写CRON表达式</td>
</tr>
<tr>
<td>executeType</td>
<td>执行类型,枚举值</td>
</tr>
<tr>
<td>processorType</td>
<td>处理器类型,枚举值</td>
</tr>
<tr>
<td>processorInfo</td>
<td>处理器参数填写类型由processorType决定如Java处理器需要填写全限定类名com.github.kfcfans.oms.processors.demo.MapReduceProcessorDemo</td>
</tr>
<tr>
<td>maxInstanceNum</td>
<td>最大实例数,该任务同时执行的数量(任务和实例就像是类和对象的关系,任务被调度执行后被称为实例)</td>
</tr>
<tr>
<td>concurrency</td>
<td>单机线程并发数表示该实例执行过程中每个Worker使用的线程数量</td>
</tr>
<tr>
<td>instanceTimeLimit</td>
<td>任务实例运行时间限制0代表无任何限制超时会被打断并判定为执行失败</td>
</tr>
<tr>
<td>instanceRetryNum</td>
<td>任务实例重试次数,整个任务失败时重试,代价大,不推荐使用</td>
</tr>
<tr>
<td>taskRetryNum</td>
<td>Task重试次数每个子Task失败后单独重试代价小推荐使用</td>
</tr>
<tr>
<td>minCpuCores</td>
<td>最小可用CPU核心数CPU可用核心数小于该值的Worker将不会执行该任务0代表无任何限制</td>
</tr>
<tr>
<td>minMemorySpace</td>
<td>最小内存大小GB可用内存小于该值的Worker将不会执行该任务0代表无任何限制</td>
</tr>
<tr>
<td>minDiskSpace</td>
<td>最小磁盘大小GB可用磁盘空间小于该值的Worker将不会执行该任务0代表无任何限制</td>
</tr>
<tr>
<td>designatedWorkers</td>
<td>指定机器执行设置该参数后只有列表中的机器允许执行该任务0代表无任何限制</td>
</tr>
<tr>
<td>maxWorkerCount</td>
<td>最大执行机器数量,限定调动执行的机器数量,空代表无限制</td>
</tr>
<tr>
<td>notifyUserIds</td>
<td>接收报警的用户ID列表</td>
</tr>
<tr>
<td>enable</td>
<td>是否启用该任务,未启用的任务不会被调度</td>
</tr>
</tbody>
</table>
<h3 id="查找任务">查找任务</h3>
<p>接口签名:<code>ResultDTO&lt;JobInfoDTO&gt; fetchJob(Long jobId)</code></p>
<p>入参任务ID</p>
<p>返回值根据success判断操作是否成功若请求成功则返回任务的详细信息</p>
<h3 id="禁用某个任务">禁用某个任务</h3>
<p>接口签名:<code>ResultDTO&lt;Void&gt; disableJob(Long jobId)</code></p>
<p>入参任务ID</p>
<p>返回值根据success判断操作是否成功</p>
<h3 id="启用某个任务">启用某个任务</h3>
<p>接口签名:<code>ResultDTO&lt;Void&gt; enableJob(Long jobId)</code></p>
<p>入参任务ID</p>
<p>返回值根据success判断操作是否成功</p>
<h3 id="删除某个任务">删除某个任务</h3>
<p>接口签名:<code>ResultDTO&lt;Void&gt; deleteJob(Long jobId)</code></p>
<p>入参任务ID</p>
<p>返回值根据success判断操作是否成功</p>
<h3 id="立即运行某个任务">立即运行某个任务</h3>
<p>接口签名:<code>ResultDTO&lt;Long&gt; runJob(Long jobId, String instanceParams)</code></p>
<p>入参任务ID + <strong>任务实例参数</strong>Processor#process方法入参<code>TaskContext</code>对象的instanceParams字段</p>
<p>返回值根据success判断操作是否成功操作成功返回对应的任务实例ID(instanceId)</p>
<h3 id="停止某个任务实例">停止某个任务实例</h3>
<p>接口签名:<code>ResultDTO&lt;Void&gt; stopInstance(Long instanceId)</code></p>
<p>入参任务实例ID</p>
<p>返回值根据success判断操作是否成功</p>
<h3 id="查询某个任务实例">查询某个任务实例</h3>
<p>接口签名:<code>ResultDTO&lt;InstanceInfoDTO&gt; fetchInstanceInfo(Long instanceId)</code></p>
<p>入参任务实例ID</p>
<p>返回值根据success判断操作是否成功操作成功返回任务实例的详细信息</p>
<h3 id="查询某个任务实例的状态">查询某个任务实例的状态</h3>
<p>接口签名:<code>ResultDTO&lt;Integer&gt; fetchInstanceStatus(Long instanceId)</code></p>
<p>入参任务实例ID</p>
<p>返回值根据success判断操作是否成功操作成功返回任务实例的状态码对应的枚举为InstanceStatus</p>
</article>
<footer class="book-footer">
<div class="flex flex-wrap justify-between">
</div>
</footer>
<div class="book-comments">
</div>
<label for="menu-control" class="hidden book-menu-overlay"></label>
</div>
<aside class="book-toc">
<nav id="TableOfContents">
<ul>
<li><a href="#依赖">依赖</a></li>
<li><a href="#简单示例">简单示例</a></li>
<li><a href="#api列表">API列表</a>
<ul>
<li><a href="#创建修改任务">创建/修改任务</a></li>
<li><a href="#查找任务">查找任务</a></li>
<li><a href="#禁用某个任务">禁用某个任务</a></li>
<li><a href="#启用某个任务">启用某个任务</a></li>
<li><a href="#删除某个任务">删除某个任务</a></li>
<li><a href="#立即运行某个任务">立即运行某个任务</a></li>
<li><a href="#停止某个任务实例">停止某个任务实例</a></li>
<li><a href="#查询某个任务实例">查询某个任务实例</a></li>
<li><a href="#查询某个任务实例的状态">查询某个任务实例的状态</a></li>
</ul>
</li>
</ul>
</nav>
</aside>
</main>
</body>
</html>

View File

@ -0,0 +1,298 @@
<!DOCTYPE html>
<html lang="en" dir=>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="theme-color" content="#FFFFFF"><meta property="og:title" content="更新日志" />
<meta property="og:description" content="" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://kfcfans.gitee.io/ohmyscheduler/docs/version/" />
<title>更新日志 | OhMyScheduler</title>
<link rel="manifest" href="/ohmyscheduler/manifest.json">
<link rel="icon" href="/ohmyscheduler/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="/ohmyscheduler/book.min.e161f1fe2b283b6a43c29a52fde96e2387fade573e78efa6701d44c8499da76b.css" integrity="sha256-4WHx/isoO2pDwppS/eluI4f63lc&#43;eO&#43;mcB1EyEmdp2s=">
<script defer src="/ohmyscheduler/en.search.min.e2f9b2f3cf3fad006da31fc1558075ea0493c82e60c3b707d1745af9a528b273.js" integrity="sha256-4vmy888/rQBtox/BVYB16gSTyC5gw7cH0XRa&#43;aUosnM="></script>
<link rel="alternate" type="application/rss+xml" href="https://kfcfans.gitee.io/ohmyscheduler/docs/version/index.xml" title="OhMyScheduler" />
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
</head>
<body dir=>
<input type="checkbox" class="hidden" id="menu-control" />
<main class="container flex">
<aside class="book-menu">
<nav>
<h2 class="book-brand">
<a href="/ohmyscheduler"><span>OhMyScheduler</span>
</a>
</h2>
<div class="book-search">
<input type="text" id="book-search-input" placeholder="Search" aria-label="Search" maxlength="64" data-hotkeys="s/" />
<div class="book-search-spinner hidden"></div>
<ul id="book-search-results"></ul>
</div>
<ul>
<li>
<span>快速开始</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/startup/1-server-startup/" class="">调度中心Server部署</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/2-worker-startup/" class="">执行器Worker初始化</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/3-processor-develop/" class="">处理器开发</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/4-console-guide/" class="">任务管理与在线运维</a>
</li>
</ul>
</li>
<li>
<span>高级特性</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/super/container/" class="">容器</a>
</li>
<li>
<a href="/ohmyscheduler/docs/super/openapi/" class="">OpenAPI</a>
</li>
</ul>
</li>
<li>
<span>更新日志</span>
<ul>
</ul>
</li>
</ul>
</nav>
<script>(function(){var menu=document.querySelector("aside.book-menu nav");addEventListener("beforeunload",function(event){localStorage.setItem("menu.scrollTop",menu.scrollTop);});menu.scrollTop=localStorage.getItem("menu.scrollTop");})();</script>
</aside>
<div class="book-page">
<header class="book-header">
<div class="flex align-center justify-between">
<label for="menu-control">
<img src="/ohmyscheduler/svg/menu.svg" class="book-icon" alt="Menu" />
</label>
<strong>更新日志</strong>
<label for="toc-control">
<img src="/ohmyscheduler/svg/toc.svg" class="book-icon" alt="Table of Contents" />
</label>
</div>
<input type="checkbox" class="hidden" id="toc-control" />
<aside class="hidden clearfix">
<nav id="TableOfContents"></nav>
</aside>
</header>
<article class="markdown"></article>
<footer class="book-footer">
<div class="flex flex-wrap justify-between">
</div>
</footer>
<label for="menu-control" class="hidden book-menu-overlay"></label>
</div>
<aside class="book-toc">
<nav id="TableOfContents"></nav>
</aside>
</main>
</body>
</html>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>更新日志 on OhMyScheduler</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/docs/version/</link>
<description>Recent content in 更新日志 on OhMyScheduler</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<atom:link href="https://kfcfans.gitee.io/ohmyscheduler/docs/version/index.xml" rel="self" type="application/rss+xml" />
</channel>
</rss>

View File

@ -0,0 +1,10 @@
'use strict';(function(){const input=document.querySelector('#book-search-input');const results=document.querySelector('#book-search-results');if(!input){return}
input.addEventListener('focus',init);input.addEventListener('keyup',search);document.addEventListener('keypress',focusSearchFieldOnKeyPress);function focusSearchFieldOnKeyPress(event){if(input===document.activeElement){return;}
const characterPressed=String.fromCharCode(event.charCode);if(!isHotkey(characterPressed)){return;}
input.focus();event.preventDefault();}
function isHotkey(character){const dataHotkeys=input.getAttribute('data-hotkeys')||'';return dataHotkeys.indexOf(character)>=0;}
function init(){input.removeEventListener('focus',init);input.required=true;loadScript('/ohmyscheduler/flexsearch.min.js');loadScript('/ohmyscheduler/en.search-data.min.415b9efb332dc463bc8ad5e36d161bfe46403b0c38923ed7353fe2eb834fd9b7.js',function(){input.required=false;search();});}
function search(){while(results.firstChild){results.removeChild(results.firstChild);}
if(!input.value){return;}
const searchHits=window.bookSearchIndex.search(input.value,10);searchHits.forEach(function(page){const li=document.createElement('li'),a=li.appendChild(document.createElement('a'));a.href=page.href;a.textContent=page.title;results.appendChild(li);});}
function loadScript(src,callback){const script=document.createElement('script');script.defer=true;script.async=false;script.src=src;script.onload=callback;document.head.appendChild(script);}})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M3 18h12v-2H3v2zM3 6v2h18V6H3zm0 7h18v-2H3v2z"/></svg>

After

Width:  |  Height:  |  Size: 185 B

View File

@ -0,0 +1,42 @@
/*
FlexSearch v0.6.30
Copyright 2019 Nextapps GmbH
Author: Thomas Wilkerling
Released under the Apache 2.0 Licence
https://github.com/nextapps-de/flexsearch
*/
'use strict';(function(K,R,w){let L;(L=w.define)&&L.amd?L([],function(){return R}):(L=w.modules)?L[K.toLowerCase()]=R:"object"===typeof exports?module.exports=R:w[K]=R})("FlexSearch",function ma(K){function w(a,c){const b=c?c.id:a&&a.id;this.id=b||0===b?b:na++;this.init(a,c);fa(this,"index",function(){return this.a?Object.keys(this.a.index[this.a.keys[0]].c):Object.keys(this.c)});fa(this,"length",function(){return this.index.length})}function L(a,c,b,d){this.u!==this.g&&(this.o=this.o.concat(b),this.u++,
d&&this.o.length>=d&&(this.u=this.g),this.u===this.g&&(this.cache&&this.j.set(c,this.o),this.F&&this.F(this.o)));return this}function S(a){const c=B();for(const b in a)if(a.hasOwnProperty(b)){const d=a[b];F(d)?c[b]=d.slice(0):G(d)?c[b]=S(d):c[b]=d}return c}function W(a,c){const b=a.length,d=O(c),e=[];for(let f=0,h=0;f<b;f++){const g=a[f];if(d&&c(g)||!d&&!c[g])e[h++]=g}return e}function P(a,c,b,d,e,f,h,g,k,l){b=ha(b,h?0:e,g,f,c,k,l);let p;g&&(g=b.page,p=b.next,b=b.result);if(h)c=this.where(h,null,
e,b);else{c=b;b=this.l;e=c.length;f=Array(e);for(h=0;h<e;h++)f[h]=b[c[h]];c=f}b=c;d&&(O(d)||(M=d.split(":"),1<M.length?d=oa:(M=M[0],d=pa)),b.sort(d));b=T(g,p,b);this.cache&&this.j.set(a,b);return b}function fa(a,c,b){Object.defineProperty(a,c,{get:b})}function r(a){return new RegExp(a,"g")}function Q(a,c){for(let b=0;b<c.length;b+=2)a=a.replace(c[b],c[b+1]);return a}function V(a,c,b,d,e,f,h,g){if(c[b])return c[b];e=e?(g-(h||g/1.5))*f+(h||g/1.5)*e:f;c[b]=e;e>=h&&(a=a[g-(e+.5>>0)],a=a[b]||(a[b]=[]),
a[a.length]=d);return e}function ba(a,c){if(a){const b=Object.keys(a);for(let d=0,e=b.length;d<e;d++){const f=b[d],h=a[f];if(h)for(let g=0,k=h.length;g<k;g++)if(h[g]===c){1===k?delete a[f]:h.splice(g,1);break}else G(h[g])&&ba(h[g],c)}}}function ca(a){let c="",b="";var d="";for(let e=0;e<a.length;e++){const f=a[e];if(f!==b)if(e&&"h"===f){if(d="a"===d||"e"===d||"i"===d||"o"===d||"u"===d||"y"===d,("a"===b||"e"===b||"i"===b||"o"===b||"u"===b||"y"===b)&&d||" "===b)c+=f}else c+=f;d=e===a.length-1?"":a[e+
1];b=f}return c}function qa(a,c){a=a.length-c.length;return 0>a?1:a?-1:0}function pa(a,c){a=a[M];c=c[M];return a<c?-1:a>c?1:0}function oa(a,c){const b=M.length;for(let d=0;d<b;d++)a=a[M[d]],c=c[M[d]];return a<c?-1:a>c?1:0}function T(a,c,b){return a?{page:a,next:c?""+c:null,result:b}:b}function ha(a,c,b,d,e,f,h){let g,k=[];if(!0===b){b="0";var l=""}else l=b&&b.split(":");const p=a.length;if(1<p){const y=B(),t=[];let v,x;var n=0,m;let I;var u=!0;let D,E=0,N,da,X,ea;l&&(2===l.length?(X=l,l=!1):l=ea=
parseInt(l[0],10));if(h){for(v=B();n<p;n++)if("not"===e[n])for(x=a[n],I=x.length,m=0;m<I;m++)v["@"+x[m]]=1;else da=n+1;if(C(da))return T(b,g,k);n=0}else N=J(e)&&e;let Y;for(;n<p;n++){const ra=n===(da||p)-1;if(!N||!n)if((m=N||e&&e[n])&&"and"!==m)if("or"===m)Y=!1;else continue;else Y=f=!0;x=a[n];if(I=x.length){if(u)if(D){var q=D.length;for(m=0;m<q;m++){u=D[m];var A="@"+u;h&&v[A]||(y[A]=1,f||(k[E++]=u))}D=null;u=!1}else{D=x;continue}A=!1;for(m=0;m<I;m++){q=x[m];var z="@"+q;const Z=f?y[z]||0:n;if(!(!Z&&
!d||h&&v[z]||!f&&y[z]))if(Z===n){if(ra){if(!ea||--ea<E)if(k[E++]=q,c&&E===c)return T(b,E+(l||0),k)}else y[z]=n+1;A=!0}else d&&(z=t[Z]||(t[Z]=[]),z[z.length]=q)}if(Y&&!A&&!d)break}else if(Y&&!d)return T(b,g,x)}if(D)if(n=D.length,h)for(m=l?parseInt(l,10):0;m<n;m++)a=D[m],v["@"+a]||(k[E++]=a);else k=D;if(d)for(E=k.length,X?(n=parseInt(X[0],10)+1,m=parseInt(X[1],10)+1):(n=t.length,m=0);n--;)if(q=t[n]){for(I=q.length;m<I;m++)if(d=q[m],!h||!v["@"+d])if(k[E++]=d,c&&E===c)return T(b,n+":"+m,k);m=0}}else!p||
e&&"not"===e[0]||(k=a[0],l&&(l=parseInt(l[0],10)));c&&(h=k.length,l&&l>h&&(l=0),l=l||0,g=l+c,g<h?k=k.slice(l,g):(g=0,l&&(k=k.slice(l))));return T(b,g,k)}function J(a){return"string"===typeof a}function F(a){return a.constructor===Array}function O(a){return"function"===typeof a}function G(a){return"object"===typeof a}function C(a){return"undefined"===typeof a}function ia(a){const c=Array(a);for(let b=0;b<a;b++)c[b]=B();return c}function B(){return Object.create(null)}function sa(){let a,c;self.onmessage=
function(b){if(b=b.data)if(b.search){const d=c.search(b.content,b.threshold?{limit:b.limit,threshold:b.threshold,where:b.where}:b.limit);self.postMessage({id:a,content:b.content,limit:b.limit,result:d})}else b.add?c.add(b.id,b.content):b.update?c.update(b.id,b.content):b.remove?c.remove(b.id):b.clear?c.clear():b.info?(b=c.info(),b.worker=a,console.log(b)):b.register&&(a=b.id,b.options.cache=!1,b.options.async=!1,b.options.worker=!1,c=(new Function(b.register.substring(b.register.indexOf("{")+1,b.register.lastIndexOf("}"))))(),
c=new c(b.options))}}function ta(a,c,b,d){a=K("flexsearch","id"+a,sa,function(f){(f=f.data)&&f.result&&d(f.id,f.content,f.result,f.limit,f.where,f.cursor,f.suggest)},c);const e=ma.toString();b.id=c;a.postMessage({register:e,options:b,id:c});return a}const H={encode:"icase",f:"forward",split:/\W+/,cache:!1,async:!1,g:!1,D:!1,a:!1,b:9,threshold:0,depth:0},ja={memory:{encode:"extra",f:"strict",threshold:0,b:1},speed:{encode:"icase",f:"strict",threshold:1,b:3,depth:2},match:{encode:"extra",f:"full",threshold:1,
b:3},score:{encode:"extra",f:"strict",threshold:1,b:9,depth:4},balance:{encode:"balance",f:"strict",threshold:0,b:3,depth:3},fast:{encode:"icase",f:"strict",threshold:8,b:9,depth:1}},aa=[];let na=0;const ka={},la={};w.create=function(a,c){return new w(a,c)};w.registerMatcher=function(a){for(const c in a)a.hasOwnProperty(c)&&aa.push(r(c),a[c]);return this};w.registerEncoder=function(a,c){U[a]=c.bind(U);return this};w.registerLanguage=function(a,c){ka[a]=c.filter;la[a]=c.stemmer;return this};w.encode=
function(a,c){return U[a](c)};w.prototype.init=function(a,c){this.v=[];if(c){var b=c.preset;a=c}else a||(a=H),b=a.preset;c={};J(a)?(c=ja[a],a={}):b&&(c=ja[b]);if(b=a.worker)if("undefined"===typeof Worker)a.worker=!1,this.m=null;else{var d=parseInt(b,10)||4;this.C=-1;this.u=0;this.o=[];this.F=null;this.m=Array(d);for(var e=0;e<d;e++)this.m[e]=ta(this.id,e,a,L.bind(this))}this.f=a.tokenize||c.f||this.f||H.f;this.split=C(b=a.split)?this.split||H.split:J(b)?r(b):b;this.D=a.rtl||this.D||H.D;this.async=
"undefined"===typeof Promise||C(b=a.async)?this.async||H.async:b;this.g=C(b=a.worker)?this.g||H.g:b;this.threshold=C(b=a.threshold)?c.threshold||this.threshold||H.threshold:b;this.b=C(b=a.resolution)?b=c.b||this.b||H.b:b;b<=this.threshold&&(this.b=this.threshold+1);this.depth="strict"!==this.f||C(b=a.depth)?c.depth||this.depth||H.depth:b;this.w=(b=C(b=a.encode)?c.encode||H.encode:b)&&U[b]&&U[b].bind(U)||(O(b)?b:this.w||!1);(b=a.matcher)&&this.addMatcher(b);if(b=(c=a.lang)||a.filter){J(b)&&(b=ka[b]);
if(F(b)){d=this.w;e=B();for(var f=0;f<b.length;f++){var h=d?d(b[f]):b[f];e[h]=1}b=e}this.filter=b}if(b=c||a.stemmer){var g;c=J(b)?la[b]:b;d=this.w;e=[];for(g in c)c.hasOwnProperty(g)&&(f=d?d(g):g,e.push(r(f+"($|\\W)"),d?d(c[g]):c[g]));this.stemmer=g=e}this.a=e=(b=a.doc)?S(b):this.a||H.a;this.i=ia(this.b-(this.threshold||0));this.h=B();this.c=B();if(e){this.l=B();a.doc=null;g=e.index={};c=e.keys=[];d=e.field;f=e.tag;h=e.store;F(e.id)||(e.id=e.id.split(":"));if(h){var k=B();if(J(h))k[h]=1;else if(F(h))for(let l=
0;l<h.length;l++)k[h[l]]=1;else G(h)&&(k=h);e.store=k}if(f){this.G=B();h=B();if(d)if(J(d))h[d]=a;else if(F(d))for(k=0;k<d.length;k++)h[d[k]]=a;else G(d)&&(h=d);F(f)||(e.tag=f=[f]);for(d=0;d<f.length;d++)this.G[f[d]]=B();this.I=f;d=h}if(d){let l;F(d)||(G(d)?(l=d,e.field=d=Object.keys(d)):e.field=d=[d]);for(e=0;e<d.length;e++)f=d[e],F(f)||(l&&(a=l[f]),c[e]=f,d[e]=f.split(":")),g[f]=new w(a)}a.doc=b}this.B=!0;this.j=(this.cache=b=C(b=a.cache)?this.cache||H.cache:b)?new ua(b):!1;return this};w.prototype.encode=
function(a){a&&(aa.length&&(a=Q(a,aa)),this.v.length&&(a=Q(a,this.v)),this.w&&(a=this.w(a)),this.stemmer&&(a=Q(a,this.stemmer)));return a};w.prototype.addMatcher=function(a){const c=this.v;for(const b in a)a.hasOwnProperty(b)&&c.push(r(b),a[b]);return this};w.prototype.add=function(a,c,b,d,e){if(this.a&&G(a))return this.A("add",a,c);if(c&&J(c)&&(a||0===a)){var f="@"+a;if(this.c[f]&&!d)return this.update(a,c);if(this.g)return++this.C>=this.m.length&&(this.C=0),this.m[this.C].postMessage({add:!0,id:a,
content:c}),this.c[f]=""+this.C,b&&b(),this;if(!e){if(this.async&&"function"!==typeof importScripts){let t=this;f=new Promise(function(v){setTimeout(function(){t.add(a,c,null,d,!0);t=null;v()})});if(b)f.then(b);else return f;return this}if(b)return this.add(a,c,null,d,!0),b(),this}c=this.encode(c);if(!c.length)return this;b=this.f;e=O(b)?b(c):c.split(this.split);this.filter&&(e=W(e,this.filter));const n=B();n._ctx=B();const m=e.length,u=this.threshold,q=this.depth,A=this.b,z=this.i,y=this.D;for(let t=
0;t<m;t++){var h=e[t];if(h){var g=h.length,k=(y?t+1:m-t)/m,l="";switch(b){case "reverse":case "both":for(var p=g;--p;)l=h[p]+l,V(z,n,l,a,y?1:(g-p)/g,k,u,A-1);l="";case "forward":for(p=0;p<g;p++)l+=h[p],V(z,n,l,a,y?(p+1)/g:1,k,u,A-1);break;case "full":for(p=0;p<g;p++){const v=(y?p+1:g-p)/g;for(let x=g;x>p;x--)l=h.substring(p,x),V(z,n,l,a,v,k,u,A-1)}break;default:if(g=V(z,n,h,a,1,k,u,A-1),q&&1<m&&g>=u)for(g=n._ctx[h]||(n._ctx[h]=B()),h=this.h[h]||(this.h[h]=ia(A-(u||0))),k=t-q,l=t+q+1,0>k&&(k=0),l>
m&&(l=m);k<l;k++)k!==t&&V(h,g,e[k],a,0,A-(k<t?t-k:k-t),u,A-1)}}}this.c[f]=1;this.B=!1}return this};w.prototype.A=function(a,c,b){if(F(c)){var d=c.length;if(d--){for(var e=0;e<d;e++)this.A(a,c[e]);return this.A(a,c[d],b)}}else{var f=this.a.index,h=this.a.keys,g=this.a.tag;e=this.a.store;var k;var l=this.a.id;d=c;for(var p=0;p<l.length;p++)d=d[l[p]];if("remove"===a&&(delete this.l[d],l=h.length,l--)){for(c=0;c<l;c++)f[h[c]].remove(d);return f[h[l]].remove(d,b)}if(g){for(k=0;k<g.length;k++){var n=g[k];
var m=c;l=n.split(":");for(p=0;p<l.length;p++)m=m[l[p]];m="@"+m}k=this.G[n];k=k[m]||(k[m]=[])}l=this.a.field;for(let u=0,q=l.length;u<q;u++){n=l[u];g=c;for(m=0;m<n.length;m++)g=g[n[m]];n=f[h[u]];m="add"===a?n.add:n.update;u===q-1?m.call(n,d,g,b):m.call(n,d,g)}if(e){b=Object.keys(e);a=B();for(f=0;f<b.length;f++)if(h=b[f],e[h]){h=h.split(":");let u,q;for(l=0;l<h.length;l++)g=h[l],u=(u||c)[g],q=(q||a)[g]=u}c=a}k&&(k[k.length]=c);this.l[d]=c}return this};w.prototype.update=function(a,c,b){if(this.a&&
G(a))return this.A("update",a,c);this.c["@"+a]&&J(c)&&(this.remove(a),this.add(a,c,b,!0));return this};w.prototype.remove=function(a,c,b){if(this.a&&G(a))return this.A("remove",a,c);var d="@"+a;if(this.c[d]){if(this.g)return this.m[this.c[d]].postMessage({remove:!0,id:a}),delete this.c[d],c&&c(),this;if(!b){if(this.async&&"function"!==typeof importScripts){let e=this;d=new Promise(function(f){setTimeout(function(){e.remove(a,null,!0);e=null;f()})});if(c)d.then(c);else return d;return this}if(c)return this.remove(a,
null,!0),c(),this}for(c=0;c<this.b-(this.threshold||0);c++)ba(this.i[c],a);this.depth&&ba(this.h,a);delete this.c[d];this.B=!1}return this};let M;w.prototype.search=function(a,c,b,d){if(G(c)){if(F(c))for(var e=0;e<c.length;e++)c[e].query=a;else c.query=a;a=c;c=1E3}else c&&O(c)?(b=c,c=1E3):c||0===c||(c=1E3);if(this.g){this.F=b;this.u=0;this.o=[];for(var f=0;f<this.g;f++)this.m[f].postMessage({search:!0,limit:c,content:a})}else{var h=[],g=a;if(G(a)&&!F(a)){b||(b=a.callback)&&(g.callback=null);var k=
a.sort;var l=a.page;c=a.limit;f=a.threshold;var p=a.suggest;a=a.query}if(this.a){f=this.a.index;const y=g.where;var n=g.bool||"or",m=g.field;let t=n;let v,x;if(m)F(m)||(m=[m]);else if(F(g)){var u=g;m=[];t=[];for(var q=0;q<g.length;q++)d=g[q],e=d.bool||n,m[q]=d.field,t[q]=e,"not"===e?v=!0:"and"===e&&(x=!0)}else m=this.a.keys;n=m.length;for(q=0;q<n;q++)u&&(g=u[q]),l&&!J(g)&&(g.page=null,g.limit=0),h[q]=f[m[q]].search(g,0);if(b)return b(P.call(this,a,t,h,k,c,p,y,l,x,v));if(this.async){const I=this;return new Promise(function(D){Promise.all(h).then(function(E){D(P.call(I,
a,t,E,k,c,p,y,l,x,v))})})}return P.call(this,a,t,h,k,c,p,y,l,x,v)}f||(f=this.threshold||0);if(!d){if(this.async&&"function"!==typeof importScripts){let y=this;f=new Promise(function(t){setTimeout(function(){t(y.search(g,c,null,!0));y=null})});if(b)f.then(b);else return f;return this}if(b)return b(this.search(g,c,null,!0)),this}if(!a||!J(a))return h;g=a;if(this.cache)if(this.B){if(b=this.j.get(a))return b}else this.j.clear(),this.B=!0;g=this.encode(g);if(!g.length)return h;b=this.f;b=O(b)?b(g):g.split(this.split);
this.filter&&(b=W(b,this.filter));u=b.length;d=!0;e=[];var A=B(),z=0;1<u&&(this.depth&&"strict"===this.f?n=!0:b.sort(qa));if(!n||(q=this.h)){const y=this.b;for(;z<u;z++){let t=b[z];if(t){if(n){if(!m)if(q[t])m=t,A[t]=1;else if(!p)return h;if(p&&z===u-1&&!e.length)n=!1,t=m||t,A[t]=0;else if(!m)continue}if(!A[t]){const v=[];let x=!1,I=0;const D=n?q[m]:this.i;if(D){let E;for(let N=0;N<y-f;N++)if(E=D[N]&&D[N][t])v[I++]=E,x=!0}if(x)m=t,e[e.length]=1<I?v.concat.apply([],v):v[0];else if(!p){d=!1;break}A[t]=
1}}}}else d=!1;d&&(h=ha(e,c,l,p));this.cache&&this.j.set(a,h);return h}};w.prototype.find=function(a,c){return this.where(a,c,1)[0]||null};w.prototype.where=function(a,c,b,d){const e=this.l,f=[];let h=0;let g;var k;let l;if(G(a)){b||(b=c);var p=Object.keys(a);var n=p.length;g=!1;if(1===n&&"id"===p[0])return[e[a.id]];if((k=this.I)&&!d)for(var m=0;m<k.length;m++){var u=k[m],q=a[u];if(!C(q)){l=this.G[u]["@"+q];if(0===--n)return l;p.splice(p.indexOf(u),1);delete a[u];break}}k=Array(n);for(m=0;m<n;m++)k[m]=
p[m].split(":")}else{if(O(a)){c=d||Object.keys(e);b=c.length;for(p=0;p<b;p++)n=e[c[p]],a(n)&&(f[h++]=n);return f}if(C(c))return[e[a]];if("id"===a)return[e[c]];p=[a];n=1;k=[a.split(":")];g=!0}d=l||d||Object.keys(e);m=d.length;for(u=0;u<m;u++){q=l?d[u]:e[d[u]];let A=!0;for(let z=0;z<n;z++){g||(c=a[p[z]]);const y=k[z],t=y.length;let v=q;if(1<t)for(let x=0;x<t;x++)v=v[y[x]];else v=v[y[0]];if(v!==c){A=!1;break}}if(A&&(f[h++]=q,b&&h===b))break}return f};w.prototype.info=function(){if(this.g)for(let a=0;a<
this.g;a++)this.m[a].postMessage({info:!0,id:this.id});else return{id:this.id,items:this.length,cache:this.cache&&this.cache.s?this.cache.s.length:!1,matcher:aa.length+(this.v?this.v.length:0),worker:this.g,threshold:this.threshold,depth:this.depth,resolution:this.b,contextual:this.depth&&"strict"===this.f}};w.prototype.clear=function(){return this.destroy().init()};w.prototype.destroy=function(){this.cache&&(this.j.clear(),this.j=null);this.i=this.h=this.c=null;if(this.a){const a=this.a.keys;for(let c=
0;c<a.length;c++)this.a.index[a[c]].destroy();this.a=this.l=null}return this};w.prototype.export=function(a){const c=!a||C(a.serialize)||a.serialize;if(this.a){const d=!a||C(a.doc)||a.doc;var b=!a||C(a.index)||a.index;a=[];let e=0;if(b)for(b=this.a.keys;e<b.length;e++){const f=this.a.index[b[e]];a[e]=[f.i,f.h,Object.keys(f.c)]}d&&(a[e]=this.l)}else a=[this.i,this.h,Object.keys(this.c)];c&&(a=JSON.stringify(a));return a};w.prototype.import=function(a,c){if(!c||C(c.serialize)||c.serialize)a=JSON.parse(a);
const b=B();if(this.a){var d=!c||C(c.doc)||c.doc,e=0;if(!c||C(c.index)||c.index){c=this.a.keys;const h=c.length;for(var f=a[0][2];e<f.length;e++)b[f[e]]=1;for(e=0;e<h;e++){f=this.a.index[c[e]];const g=a[e];g&&(f.i=g[0],f.h=g[1],f.c=b)}}d&&(this.l=G(d)?d:a[e])}else{d=a[2];for(e=0;e<d.length;e++)b[d[e]]=1;this.i=a[0];this.h=a[1];this.c=b}};const va=function(){const a=r("\\s+"),c=r("[^a-z0-9 ]"),b=[r("[-/]")," ",c,"",a," "];return function(d){return ca(Q(d.toLowerCase(),b))}}(),U={icase:function(a){return a.toLowerCase()},
simple:function(){const a=r("\\s+"),c=r("[^a-z0-9 ]"),b=r("[-/]"),d=r("[\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5]"),e=r("[\u00e8\u00e9\u00ea\u00eb]"),f=r("[\u00ec\u00ed\u00ee\u00ef]"),h=r("[\u00f2\u00f3\u00f4\u00f5\u00f6\u0151]"),g=r("[\u00f9\u00fa\u00fb\u00fc\u0171]"),k=r("[\u00fd\u0177\u00ff]"),l=r("\u00f1"),p=r("[\u00e7c]"),n=r("\u00df"),m=r(" & "),u=[d,"a",e,"e",f,"i",h,"o",g,"u",k,"y",l,"n",p,"k",n,"s",m," and ",b," ",c,"",a," "];return function(q){q=Q(q.toLowerCase(),u);return" "===q?"":q}}(),advanced:function(){const a=
r("ae"),c=r("ai"),b=r("ay"),d=r("ey"),e=r("oe"),f=r("ue"),h=r("ie"),g=r("sz"),k=r("zs"),l=r("ck"),p=r("cc"),n=r("sh"),m=r("th"),u=r("dt"),q=r("ph"),A=r("pf"),z=r("ou"),y=r("uo"),t=[a,"a",c,"ei",b,"ei",d,"ei",e,"o",f,"u",h,"i",g,"s",k,"s",n,"s",l,"k",p,"k",m,"t",u,"t",q,"f",A,"f",z,"o",y,"u"];return function(v,x){if(!v)return v;v=this.simple(v);2<v.length&&(v=Q(v,t));x||1<v.length&&(v=ca(v));return v}}(),extra:function(){const a=r("p"),c=r("z"),b=r("[cgq]"),d=r("n"),e=r("d"),f=r("[vw]"),h=r("[aeiouy]"),
g=[a,"b",c,"s",b,"k",d,"m",e,"t",f,"f",h,""];return function(k){if(!k)return k;k=this.advanced(k,!0);if(1<k.length){k=k.split(" ");for(let l=0;l<k.length;l++){const p=k[l];1<p.length&&(k[l]=p[0]+Q(p.substring(1),g))}k=k.join(" ");k=ca(k)}return k}}(),balance:va},ua=function(){function a(c){this.clear();this.H=!0!==c&&c}a.prototype.clear=function(){this.cache=B();this.count=B();this.index=B();this.s=[]};a.prototype.set=function(c,b){if(this.H&&C(this.cache[c])){let d=this.s.length;if(d===this.H){d--;
const e=this.s[d];delete this.cache[e];delete this.count[e];delete this.index[e]}this.index[c]=d;this.s[d]=c;this.count[c]=-1;this.cache[c]=b;this.get(c)}else this.cache[c]=b};a.prototype.get=function(c){const b=this.cache[c];if(this.H&&b){var d=++this.count[c];const f=this.index;let h=f[c];if(0<h){const g=this.s;for(var e=h;this.count[g[--h]]<=d&&-1!==h;);h++;if(h!==e){for(d=e;d>h;d--)e=g[d-1],g[d]=e,f[e]=d;g[h]=c;f[c]=h}}}return b};return a}();return w}(function(){const K={},R="undefined"!==typeof Blob&&
"undefined"!==typeof URL&&URL.createObjectURL;return function(w,L,S,W,P){S=R?URL.createObjectURL(new Blob(["("+S.toString()+")()"],{type:"text/javascript"})):w+".min.js";w+="-"+L;K[w]||(K[w]=[]);K[w][P]=new Worker(S);K[w][P].onmessage=W;return K[w][P]}}()),this);

Binary file not shown.

View File

@ -0,0 +1,388 @@
<!DOCTYPE html>
<html lang="en" dir=>
<head>
<meta name="generator" content="Hugo 0.71.0" />
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="项目地址 GitHub | Gitee
产品介绍 OhMyScheduler是基于Akka架构的一款分布式调度与计算框架对标 Alibaba SchedulerX2.0),其主要功能特性如下:
使用简单提供前端Web界面允许开发者可视化地完成调度任务的管理增、删、改、查、任务运行状态监控和运行日志查看等功能。 定时策略完善支持CRON表达式、固定频率、固定延迟和API四种定时调度策略。 执行模式丰富支持单机、广播、Map、MapReduce四种执行模式其中Map/MapReduce处理器能使开发者寥寥数行代码便获得集群分布式计算的能力。 执行器支持广泛支持Spring Bean、普通Java对象、Shell、Python等处理器应用范围广比如广播执行&#43;Shell脚本用来清理日志 运维便捷支持在线日志功能执行器产生的日志可以在前端控制台页面实时显示降低debug成本极大地提高开发效率。 依赖精简最小仅依赖关系型数据库MySQL/Oracle/MS SQLServer&hellip;扩展依赖为MongoDB用于存储庞大的在线日志。 高可用&amp;高性能:调度服务器经过精心设计,一改其他调度框架基于数据库锁的策略,实现了无锁化调度。部署多个调度服务器可以同时实现高可用和性能的提升(支持无限的水平扩展)。 故障转移与恢复:任务执行失败后,可根据配置的重试策略完成重试,只要执行器集群有足够的计算节点,任务就能顺利完成。 适用场景 有定时执行需求的业务场景:如每天凌晨全量同步数据、生成业务报表等。 有需要全部机器一同执行的业务场景:如日志清理。 有需要分布式处理的业务场景比如需要更新一大批数据单机执行耗时非常长可以使用Map/MapReduce处理器完成任务的分发调动整个集群加速计算。 同类产品对比 QuartZ xxl-job SchedulerX 2.0 OhMyScheduler 定时类型 CRON CRON CRON、固定频率、固定延迟、OpenAPI CRON、固定频率、固定延迟、OpenAPI 任务类型 内置Java 内置Java、GLUE Java、Shell、Python等脚本 内置Java、外置JavaFatJar、Shell、Python等脚本 内置Java、外置Java容器、Shell、Python等脚本 分布式任务 无 静态分片 MapReduce动态分片 MapReduce动态分片 在线任务治理 不支持 支持 支持 支持 日志白屏化 不支持 支持 不支持 支持 调度方式及性能 基于数据库锁,有性能瓶颈 基于数据库锁,有性能瓶颈 不详 无锁化设计,性能强劲无上限 报警监控 无 邮件 短信 邮件,提供接口允许开发者扩展 系统依赖 MySQL MySQL 人民币(公测期间免费,哎,帮打个广告吧) 任意Spring Data Jpa支持的关系型数据库MySQL、Oracle&hellip; DAG工作流 不支持 不支持 支持 暂不支持,有明确开发计划 ">
<meta name="theme-color" content="#FFFFFF"><meta property="og:title" content="介绍" />
<meta property="og:description" content="" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://kfcfans.gitee.io/ohmyscheduler/" />
<title>介绍 | OhMyScheduler</title>
<link rel="manifest" href="/ohmyscheduler/manifest.json">
<link rel="icon" href="/ohmyscheduler/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="/ohmyscheduler/book.min.e161f1fe2b283b6a43c29a52fde96e2387fade573e78efa6701d44c8499da76b.css" integrity="sha256-4WHx/isoO2pDwppS/eluI4f63lc&#43;eO&#43;mcB1EyEmdp2s=">
<script defer src="/ohmyscheduler/en.search.min.e2f9b2f3cf3fad006da31fc1558075ea0493c82e60c3b707d1745af9a528b273.js" integrity="sha256-4vmy888/rQBtox/BVYB16gSTyC5gw7cH0XRa&#43;aUosnM="></script>
<link rel="alternate" type="application/rss+xml" href="https://kfcfans.gitee.io/ohmyscheduler/index.xml" title="OhMyScheduler" />
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
</head>
<body dir=>
<input type="checkbox" class="hidden" id="menu-control" />
<main class="container flex">
<aside class="book-menu">
<nav>
<h2 class="book-brand">
<a href="/ohmyscheduler"><span>OhMyScheduler</span>
</a>
</h2>
<div class="book-search">
<input type="text" id="book-search-input" placeholder="Search" aria-label="Search" maxlength="64" data-hotkeys="s/" />
<div class="book-search-spinner hidden"></div>
<ul id="book-search-results"></ul>
</div>
<ul>
<li>
<span>快速开始</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/startup/1-server-startup/" class="">调度中心Server部署</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/2-worker-startup/" class="">执行器Worker初始化</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/3-processor-develop/" class="">处理器开发</a>
</li>
<li>
<a href="/ohmyscheduler/docs/startup/4-console-guide/" class="">任务管理与在线运维</a>
</li>
</ul>
</li>
<li>
<span>高级特性</span>
<ul>
<li>
<a href="/ohmyscheduler/docs/super/container/" class="">容器</a>
</li>
<li>
<a href="/ohmyscheduler/docs/super/openapi/" class="">OpenAPI</a>
</li>
</ul>
</li>
<li>
<span>更新日志</span>
<ul>
</ul>
</li>
</ul>
</nav>
<script>(function(){var menu=document.querySelector("aside.book-menu nav");addEventListener("beforeunload",function(event){localStorage.setItem("menu.scrollTop",menu.scrollTop);});menu.scrollTop=localStorage.getItem("menu.scrollTop");})();</script>
</aside>
<div class="book-page">
<header class="book-header">
<div class="flex align-center justify-between">
<label for="menu-control">
<img src="/ohmyscheduler/svg/menu.svg" class="book-icon" alt="Menu" />
</label>
<strong>介绍</strong>
<label for="toc-control">
<img src="/ohmyscheduler/svg/toc.svg" class="book-icon" alt="Table of Contents" />
</label>
</div>
</header>
<article class="markdown"><p><img src="oms-logo.png" alt="logo" /></p>
<h2 id="项目地址">项目地址</h2>
<p><a href="https://github.com/KFCFans/OhMyScheduler">GitHub</a> | <a href="https://gitee.com/KFCFans/OhMyScheduler">Gitee</a></p>
<h2 id="产品介绍">产品介绍</h2>
<p><strong>OhMyScheduler是基于Akka架构的一款分布式调度与计算框架对标 Alibaba SchedulerX2.0),其主要功能特性如下</strong></p>
<ul>
<li>使用简单提供前端Web界面允许开发者可视化地完成调度任务的管理增、删、改、查、任务运行状态监控和运行日志查看等功能。</li>
<li>定时策略完善支持CRON表达式、固定频率、固定延迟和API四种定时调度策略。</li>
<li>执行模式丰富支持单机、广播、Map、MapReduce四种执行模式其中Map/MapReduce处理器能使开发者寥寥数行代码便获得集群分布式计算的能力。</li>
<li>执行器支持广泛支持Spring Bean、普通Java对象、Shell、Python等处理器应用范围广比如广播执行+Shell脚本用来清理日志</li>
<li>运维便捷支持在线日志功能执行器产生的日志可以在前端控制台页面实时显示降低debug成本极大地提高开发效率。</li>
<li>依赖精简最小仅依赖关系型数据库MySQL/Oracle/MS SQLServer&hellip;扩展依赖为MongoDB用于存储庞大的在线日志</li>
<li>高可用&amp;高性能:调度服务器经过精心设计,一改其他调度框架基于数据库锁的策略,实现了无锁化调度。部署多个调度服务器可以同时实现高可用和性能的提升(支持无限的水平扩展)。</li>
<li>故障转移与恢复:任务执行失败后,可根据配置的重试策略完成重试,只要执行器集群有足够的计算节点,任务就能顺利完成。</li>
</ul>
<h2 id="适用场景">适用场景</h2>
<ul>
<li>有定时执行需求的业务场景:如每天凌晨全量同步数据、生成业务报表等。</li>
<li>有需要全部机器一同执行的业务场景:如日志清理。</li>
<li>有需要分布式处理的业务场景比如需要更新一大批数据单机执行耗时非常长可以使用Map/MapReduce处理器完成任务的分发调动整个集群加速计算。</li>
</ul>
<h2 id="同类产品对比">同类产品对比</h2>
<table>
<thead>
<tr>
<th></th>
<th>QuartZ</th>
<th>xxl-job</th>
<th>SchedulerX 2.0</th>
<th>OhMyScheduler</th>
</tr>
</thead>
<tbody>
<tr>
<td>定时类型</td>
<td>CRON</td>
<td>CRON</td>
<td>CRON、固定频率、固定延迟、OpenAPI</td>
<td><strong>CRON、固定频率、固定延迟、OpenAPI</strong></td>
</tr>
<tr>
<td>任务类型</td>
<td>内置Java</td>
<td>内置Java、GLUE Java、Shell、Python等脚本</td>
<td>内置Java、外置JavaFatJar、Shell、Python等脚本</td>
<td><strong>内置Java、外置Java容器、Shell、Python等脚本</strong></td>
</tr>
<tr>
<td>分布式任务</td>
<td></td>
<td>静态分片</td>
<td>MapReduce动态分片</td>
<td><strong>MapReduce动态分片</strong></td>
</tr>
<tr>
<td>在线任务治理</td>
<td>不支持</td>
<td>支持</td>
<td>支持</td>
<td><strong>支持</strong></td>
</tr>
<tr>
<td>日志白屏化</td>
<td>不支持</td>
<td>支持</td>
<td>不支持</td>
<td><strong>支持</strong></td>
</tr>
<tr>
<td>调度方式及性能</td>
<td>基于数据库锁,有性能瓶颈</td>
<td>基于数据库锁,有性能瓶颈</td>
<td>不详</td>
<td><strong>无锁化设计,性能强劲无上限</strong></td>
</tr>
<tr>
<td>报警监控</td>
<td></td>
<td>邮件</td>
<td>短信</td>
<td><strong>邮件,提供接口允许开发者扩展</strong></td>
</tr>
<tr>
<td>系统依赖</td>
<td>MySQL</td>
<td>MySQL</td>
<td>人民币(公测期间免费,哎,帮打个广告吧)</td>
<td><strong>任意Spring Data Jpa支持的关系型数据库MySQL、Oracle&hellip;</strong></td>
</tr>
<tr>
<td>DAG工作流</td>
<td>不支持</td>
<td>不支持</td>
<td>支持</td>
<td>暂不支持,有明确开发计划</td>
</tr>
</tbody>
</table>
</article>
<footer class="book-footer">
<div class="flex flex-wrap justify-between">
</div>
</footer>
<div class="book-comments">
</div>
<label for="menu-control" class="hidden book-menu-overlay"></label>
</div>
</main>
</body>
</html>

View File

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>介绍 on OhMyScheduler</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/</link>
<description>Recent content in 介绍 on OhMyScheduler</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<atom:link href="https://kfcfans.gitee.io/ohmyscheduler/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>容器</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/docs/super/container/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>https://kfcfans.gitee.io/ohmyscheduler/docs/super/container/</guid>
<description>什么是容器? 介绍 OhMyScheduler的容器技术允许开发者开发独立于Worker项目之外Java处理器简单来说就是以Maven工程项目的维度去组织一堆Java文件开发者开发的众多脚本处理器进而兼具开发效率和可维护性。
用途举例 比如突然出现了某个数据库数据清理任务与主业务无关写进原本的项目工程中不太优雅这时候就可以单独创建一个用于数据操作的容器在里面完成处理器的开发通过OhMyScheduler的容器部署技术在Worker集群上被加载执行。 比如常见的日志清理啊机器状态上报啊对于广大Java程序员来说也许并不是很会写shell脚本此时也可以借用agent+容器技术利用Java完成各项原本需要通过脚本进行的操作。 (感觉例子举的都不是很好&amp;hellip;这个东西嘛,只可意会不可言传,大家努力理解一下吧~超好用哦~)
生成容器模版 为了方便开发者使用,最新版本的前端页面已经支持容器工程模版的自动生成,开发者仅需要填入相关信息即可下载容器模版开始开发。 Group对应Maven的&amp;lt;groupId&amp;gt;标签,一般填入倒写的公司域名。 Artifact对于Maven的&amp;lt;artifactId&amp;gt;标签,填入代表该容器的唯一标示。 Name对应Maven的&amp;lt;name&amp;gt;标签,填入该容器名称。 Package Name包名代表了的容器工程内部所使用的包名警告包名一旦生成后请勿更改否则会导致运行时容器加载错误当然如有必须修改包名的需求可以尝试替换/resource下以oms-worker-container开头的所有文件相关的值。 Java Version容器工程的Java版本请务必与容器目标部署Worker平台的Java版本保持一致。 开发容器工程 完成容器模版创建后下载解压会得到如下结构的Java工程
oms-template-origin // 工程名称,可以自由更改 ├── pom.xml └── src ├── main │ ├── java │ │ └── cn │ │ └── edu │ │ └── zju │ │ └── tjq │ │ └── container │ │ └── samples // 所有处理器代码必须位于该目录下,其余类随意 │ └── resources // 严禁随意更改以下两个配置文件(允许添加,不允许更改现有内容) │ ├── oms-worker-container-spring-context.xml │ └── oms-worker-container.</description>
</item>
<item>
<title>调度中心Server部署</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/1-server-startup/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/1-server-startup/</guid>
<description>环境要求 Open JDK 8+
Apache Maven 3+
任意 Spring Data Jpa 支持的关系型数据库MySQL/Oracle/MS SQLServer&amp;hellip;
MongoDB可选任意支持GridFS的mongoDB版本4.2.6测试通过,其余未经测试,仅从理论角度分析可用),缺失该组件的情况下将无法使用在线日志、容器部署等扩展功能
初始化关系数据库 调度服务器oh-my-scheduler-server的持久化层基于Spring Boot Jpa实现对于能够直连数据库的应用开发者仅需完成数据库的创建即运行SQLCREATE database if NOT EXISTS oms-product default character set utf8mb4 collate utf8mb4_unicode_ci;`
OhMyScheduler支持环境隔离提供日常daily、预发pre和线上product三套环境请根据使用的环境分别部署对应的数据库oms-daily、oms-pre和oms-product。 调度服务器属于时间敏感应用强烈建议检查当前数据库所使用的时区信息show variables like &amp;quot;%time_zone%&amp;quot;;务必确保time_zone代表的时区与JDBC URL中serverTimezone字段代表的时区一致 手动建表表SQL文件下载地址 部署调度服务器—源码编译 调度服务器oh-my-scheduler-server支持任意的水平扩展即多实例集群部署仅需要在同一个局域网内启动新的服务器实例性能强劲无上限
调度服务器oh-my-scheduler-server为了支持环境隔离分别采用了日常application-daily.properties、预发application-pre.properties和线上application-product.properties三套配置文件请根据实际需求进行修改以下为配置文件详解。
配置项 含义 可选 server.port SpringBoot配置HTTP端口号默认7700 否 oms.</description>
</item>
<item>
<title>OpenAPI</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/docs/super/openapi/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>https://kfcfans.gitee.io/ohmyscheduler/docs/super/openapi/</guid>
<description>OpenAPI允许开发者通过接口来完成手工的操作让系统整体变得更加灵活。开发者可以基于API便捷地扩展OhMyScheduler原有的功能。 依赖 最新依赖版本请参考Maven中央仓库推荐地址&amp;amp;备用地址。
&amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;com.github.kfcfans&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;oh-my-scheduler-client&amp;lt;/artifactId&amp;gt; &amp;lt;version&amp;gt;1.2.0&amp;lt;/version&amp;gt; &amp;lt;/dependency&amp;gt; 简单示例 // 初始化 client需要server地址和应用名称作为参数 OhMyClient ohMyClient = new OhMyClient(&amp;#34;127.0.0.1:7700&amp;#34;, &amp;#34;oms-test&amp;#34;); // 调用相关的API ohMyClient.stopInstance(1586855173043L) API列表 创建/修改任务 接口签名ResultDTO&amp;lt;Long&amp;gt; saveJob(ClientJobInfo newJobInfo)
入参:任务信息(详细说明见下表,也可以参考前端任务创建各参数的正确填法)
返回值ResultDTO根据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.</description>
</item>
<item>
<title>执行器Worker初始化</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/2-worker-startup/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/2-worker-startup/</guid>
<description>基于宿主应用的执行器初始化 宿主应用即原有的业务应用,假如需要调度执行的任务与当前业务有较为紧密的联系,建议采取该方式。
首先添加相关的jar包依赖最新依赖版本请参考maven中央仓库推荐地址&amp;amp;备用地址
&amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;com.github.kfcfans&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;oh-my-scheduler-worker&amp;lt;/artifactId&amp;gt; &amp;lt;version&amp;gt;1.2.0&amp;lt;/version&amp;gt; &amp;lt;/dependency&amp;gt; 其次填写执行器客户端配置文件OhMyConfig各参数说明如下表所示
属性名称 含义 默认值 appName 宿主应用名称,需要提前在控制台完成注册 无,必填项,否则启动报错 port Worker工作端口 27777 serverAddress 调度中心oh-my-scheduler-server地址列表 无,必填项,否则启动报错 storeStrategy 本地存储策略,枚举值磁盘/内存大型MapReduce等会产生大量Task的任务推荐使用磁盘降低内存压力否则建议使用内存加速计算 StoreStrategy.DISK磁盘 maxResultLength 每个Task返回结果的默认长度超长将被截断。过长可能导致网络拥塞 8096 enableTestMode 是否启用测试模式启用后无需Server也能顺利启动OhMyScheduler-Worker用于处理器本地的单元测试 false 最后,初始化客户端,完成执行器的启动,代码示例如下:
@Configuration public class OhMySchedulerConfig { @Bean public OhMyWorker initOMS() throws Exception { // 服务器HTTP地址端口号为 server.port而不是 ActorSystem port List&amp;lt;String&amp;gt; serverAddress = Lists.</description>
</item>
<item>
<title>处理器开发</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/3-processor-develop/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/3-processor-develop/</guid>
<description>处理器概述 OhMyScheduler当前支持Shell、Python等脚本处理器和Java处理器。脚本处理器只需要开发者完成脚本的编写xxx.sh / xxx.py在控制台填入脚本内容即可本章不再赘述。本章将重点阐述Java处理器开发方法与使用技巧。
Java处理器可根据代码所处位置划分为内置Java处理器和容器Java处理器前者直接集成在宿主应用也就是接入本系统的业务应用一般用来处理业务需求后者可以在一个独立的轻量级的Java工程中开发通过容器技术详见容器章节被worker集群热加载提供Java的“脚本能力”一般用于处理灵活多变的需求。 Java处理器可根据对象创建者划分为SpringBean处理器和普通Java对象处理器前者由Spring IOC容器完成处理器的创建和初始化后者则有OhMyScheduler维护其状态。如果宿主应用支持Spring强烈建议使用SpringBean处理器开发者仅需要将Processor注册进Spring IOC容器一个@Component注解或一句bean配置。 Java处理器可根据功能划分为单机处理器、广播处理器、Map处理器和MapReduce处理器。 单机处理器BasicProcessor对应了单机任务即某个任务的某次运行只会有某一台机器的某一个线程参与运算。 广播处理器BroadcastProcessor对应了广播任务即某个任务的某次运行会调动集群内所有机器参与运算。 Map处理器MapProcessor对应了Map任务即某个任务在运行过程中允许产生子任务并分发到其他机器进行运算。 MapReduce处理器MapReduceProcessor对应了MapReduce任务在Map任务的基础上增加了所有任务结束后的汇总统计。 核心方法process 任意Java处理器都需要实现处理的核心方法其接口签名如下
ProcessResult process(TaskContext context) throws Exception; 方法入参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造成巨大的压力 方法的返回值为ProcessResult代表了本次Task执行的结果包含success和msg两个属性分别用于传递Task是否执行成功和Task需要返回的信息。</description>
</item>
<item>
<title>任务管理与在线运维</title>
<link>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/4-console-guide/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>https://kfcfans.gitee.io/ohmyscheduler/docs/startup/4-console-guide/</guid>
<description>前端控制台允许开发者可视化地进行任务增、删、改、查等管理操作,同时也能直观地看到任务的运行数据,包括运行状态、详情和在线日志等。以下为对控制台的详细介绍: 主页 展示了系统整体的概览和集群Worker列表。
任务创建 创建需要被调度执行的任务,入口为主页 -&amp;gt; 任务管理 -&amp;gt; 新建任务。
任务名称:名称,便于记忆与搜索,无特殊用途,请尽量简短(占用数据库字段空间)
任务描述:描述,无特殊作用,请尽量简短(占用数据库字段空间)
任务参数任务处理时能够获取到的参数即各个Processor的process方法入参TaskContext对象的jobParams字段进行一次处理器开发就能理解了
定时信息:由下拉框和输入框组成
API -&amp;gt; 不需要填写任何参数(填了也不起作用) CRON -&amp;gt; 填写 CRON 表达式(可以找个在线生成网站生成) 固定频率 -&amp;gt; 填写整数,单位毫秒 固定延迟 -&amp;gt; 填写整数,单位毫秒 执行配置由执行类型单机、广播和MapReduce、处理器类型和处理器参数组成后两项相互关联。
内置Java处理器 -&amp;gt; 填写该处理器的全限定类名eg, com.github.kfcfans.oms.processors.demo.MapReduceProcessorDemo Java容器 -&amp;gt; 填写容器ID#处理器全限定类名eg1#com.github.kfcfans.oms.container.DemoProcessor SHELL -&amp;gt; 填写需要处理的脚本直接复制文件内容或脚本下载连接http://xxx PYTHON -&amp;gt; 填写完整的python脚本或下载连接http://xxx 运行配置
最大实例数:该任务同时执行的数量(任务和实例就像是类和对象的关系,任务被调度执行后被称为实例) 单机线程并发数该实例执行过程中每个Worker使用的线程数量MapReduce任务生效其余无论填什么都只会使用1个线程或3个线程&amp;hellip; 运行时间限制限定任务的最大运行时间超时则视为失败单位毫秒0代表不限制超时时间。 重试配置:
任务重试次数实例级别失败了整个任务实例重试会更换TaskTracker本次任务实例的Master节点代价较大大型Map/MapReduce慎用。 子任务重试次数Task级别每个子Task失败后单独重试会更换ProcessorTracker本次任务实际执行的Worker节点代价较小推荐使用。 注对于单机任务来说假如任务重试次数和子任务重试次数都配置了1且都执行失败实际执行次数会变成4次推荐任务实例重试配置为0子任务重试次数根据实际情况配置。 机器配置用来标明允许执行任务的机器状态避开那些摇摇欲坠的机器0代表无任何限制。</description>
</item>
</channel>
</rss>

View File

@ -0,0 +1 @@
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("katex")):"function"==typeof define&&define.amd?define(["katex"],t):"object"==typeof exports?exports.renderMathInElement=t(require("katex")):e.renderMathInElement=t(e.katex)}("undefined"!=typeof self?self:this,function(e){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=1)}([function(t,r){t.exports=e},function(e,t,r){"use strict";r.r(t);var n=r(0),o=r.n(n),a=function(e,t,r){for(var n=r,o=0,a=e.length;n<t.length;){var i=t[n];if(o<=0&&t.slice(n,n+a)===e)return n;"\\"===i?n++:"{"===i?o++:"}"===i&&o--,n++}return-1},i=function(e,t,r,n){for(var o=[],i=0;i<e.length;i++)if("text"===e[i].type){var l=e[i].data,d=!0,s=0,f=void 0;for(-1!==(f=l.indexOf(t))&&(s=f,o.push({type:"text",data:l.slice(0,s)}),d=!1);;){if(d){if(-1===(f=l.indexOf(t,s)))break;o.push({type:"text",data:l.slice(s,f)}),s=f}else{if(-1===(f=a(r,l,s+t.length)))break;o.push({type:"math",data:l.slice(s+t.length,f),rawData:l.slice(s,f+r.length),display:n}),s=f+r.length}d=!d}o.push({type:"text",data:l.slice(s)})}else o.push(e[i]);return o},l=function(e,t){for(var r=function(e,t){for(var r=[{type:"text",data:e}],n=0;n<t.length;n++){var o=t[n];r=i(r,o.left,o.right,o.display||!1)}return r}(e,t.delimiters),n=document.createDocumentFragment(),a=0;a<r.length;a++)if("text"===r[a].type)n.appendChild(document.createTextNode(r[a].data));else{var l=document.createElement("span"),d=r[a].data;t.displayMode=r[a].display;try{t.preProcess&&(d=t.preProcess(d)),o.a.render(d,l,t)}catch(e){if(!(e instanceof o.a.ParseError))throw e;t.errorCallback("KaTeX auto-render: Failed to parse `"+r[a].data+"` with ",e),n.appendChild(document.createTextNode(r[a].rawData));continue}n.appendChild(l)}return n};t.default=function(e,t){if(!e)throw new Error("No element provided to render");var r={};for(var n in t)t.hasOwnProperty(n)&&(r[n]=t[n]);r.delimiters=r.delimiters||[{left:"$$",right:"$$",display:!0},{left:"\\(",right:"\\)",display:!1},{left:"\\[",right:"\\]",display:!0}],r.ignoredTags=r.ignoredTags||["script","noscript","style","textarea","pre","code"],r.ignoredClasses=r.ignoredClasses||[],r.errorCallback=r.errorCallback||console.error,r.macros=r.macros||{},function e(t,r){for(var n=0;n<t.childNodes.length;n++){var o=t.childNodes[n];if(3===o.nodeType){var a=l(o.textContent,r);n+=a.childNodes.length-1,t.replaceChild(a,o)}else 1===o.nodeType&&function(){var t=" "+o.className+" ";-1===r.ignoredTags.indexOf(o.nodeName.toLowerCase())&&r.ignoredClasses.every(function(e){return-1===t.indexOf(" "+e+" ")})&&e(o,r)}()}}(e,r)}}]).default});

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,15 @@
{
"name": "OhMyScheduler",
"short_name": "OhMyScheduler",
"start_url": "/ohmyscheduler/",
"scope": "/ohmyscheduler/",
"display": "standalone",
"background_color": "#000000",
"theme_color": "#000000",
"icons": [
{
"src": "/ohmyscheduler/favicon.svg",
"sizes": "512x512"
}
]
}

49
others/guidance/public/mermaid.min.js vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Some files were not shown because too many files have changed in this diff Show More