Browse Source

Merge remote-tracking branch 'upstream/branch-1.0.2' into branch-1.0.2

pull/2/head
gongzijian 6 years ago
parent
commit
e7d4ce569b
  1. 41
      Dockerfile
  2. 31
      conf/escheduler.conf
  3. 310
      conf/install.sh
  4. 105
      conf/run.sh
  5. 30
      conf/zoo.cfg
  6. 1
      docs/zh_CN/SUMMARY.md
  7. BIN
      docs/zh_CN/images/complement.png
  8. BIN
      docs/zh_CN/images/create-queue.png
  9. BIN
      docs/zh_CN/images/dag1.png
  10. BIN
      docs/zh_CN/images/dag2.png
  11. BIN
      docs/zh_CN/images/dag3.png
  12. BIN
      docs/zh_CN/images/dag4.png
  13. BIN
      docs/zh_CN/images/depend-node.png
  14. BIN
      docs/zh_CN/images/depend-node2.png
  15. BIN
      docs/zh_CN/images/depend-node3.png
  16. BIN
      docs/zh_CN/images/file-manage.png
  17. BIN
      docs/zh_CN/images/gant-pic.png
  18. BIN
      docs/zh_CN/images/hive_edit.png
  19. BIN
      docs/zh_CN/images/hive_edit2.png
  20. BIN
      docs/zh_CN/images/instance-detail.png
  21. BIN
      docs/zh_CN/images/instance-list.png
  22. BIN
      docs/zh_CN/images/master-jk.png
  23. BIN
      docs/zh_CN/images/mysql-jk.png
  24. BIN
      docs/zh_CN/images/mysql_edit.png
  25. BIN
      docs/zh_CN/images/postgressql_edit.png
  26. BIN
      docs/zh_CN/images/project.png
  27. BIN
      docs/zh_CN/images/run-work.png
  28. BIN
      docs/zh_CN/images/sql-node.png
  29. BIN
      docs/zh_CN/images/sql-node2.png
  30. BIN
      docs/zh_CN/images/task-list.png
  31. BIN
      docs/zh_CN/images/task-log.png
  32. BIN
      docs/zh_CN/images/task-log2.png
  33. BIN
      docs/zh_CN/images/time-schedule.png
  34. BIN
      docs/zh_CN/images/time-schedule2.png
  35. BIN
      docs/zh_CN/images/worker-jk.png
  36. BIN
      docs/zh_CN/images/worker1.png
  37. BIN
      docs/zh_CN/images/zk-jk.png
  38. 10
      docs/zh_CN/后端部署文档.md
  39. 50
      docs/zh_CN/快速上手.md
  40. 705
      docs/zh_CN/系统使用手册.md
  41. 2
      escheduler-alert/src/main/java/cn/escheduler/alert/utils/Constants.java
  42. 16
      escheduler-alert/src/main/java/cn/escheduler/alert/utils/MailUtils.java
  43. 7
      escheduler-alert/src/main/resources/alert.properties
  44. 39
      escheduler-alert/src/main/resources/mail_templates/alert_mail_template.ftl
  45. 4
      escheduler-api/pom.xml
  46. 2
      escheduler-api/src/main/java/cn/escheduler/api/service/ExecutorService.java
  47. 8
      escheduler-api/src/main/java/cn/escheduler/api/service/ProcessDefinitionService.java
  48. 3
      escheduler-api/src/main/java/cn/escheduler/api/service/UsersService.java
  49. 16
      escheduler-common/pom.xml
  50. 5
      escheduler-common/src/main/java/cn/escheduler/common/Constants.java
  51. 3
      escheduler-common/src/main/java/cn/escheduler/common/queue/TaskQueueZkImpl.java
  52. 3
      escheduler-common/src/main/java/cn/escheduler/common/utils/DependentUtils.java
  53. 9
      escheduler-common/src/main/java/cn/escheduler/common/utils/JSONUtils.java
  54. 15
      escheduler-common/src/main/java/cn/escheduler/common/utils/dependent/DependentDateUtils.java
  55. 1
      escheduler-common/src/main/resources/zookeeper.properties
  56. 11
      escheduler-common/src/test/java/cn/escheduler/common/utils/DependentUtilsTest.java
  57. 6
      escheduler-dao/pom.xml
  58. 2
      escheduler-dao/src/main/java/cn/escheduler/dao/ProcessDao.java
  59. 5
      escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ProcessInstanceMapperProvider.java
  60. 7
      escheduler-dao/src/main/java/cn/escheduler/dao/mapper/UserMapperProvider.java
  61. 4
      escheduler-server/pom.xml
  62. 34
      escheduler-server/src/main/java/cn/escheduler/server/zk/ZKMasterClient.java
  63. 4
      escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/_source/commcon.js
  64. 6
      escheduler-ui/src/js/conf/home/pages/security/pages/users/_source/createUser.vue
  65. 1
      escheduler-ui/src/js/module/i18n/locale/en_US.js
  66. 4
      escheduler-ui/src/js/module/i18n/locale/zh_CN.js
  67. 33
      install.sh
  68. 2
      sql/escheduler.sql

41
Dockerfile

@ -1,41 +0,0 @@
#Maintin by jimmy
#Email: zhengge2012@gmail.com
FROM anapsix/alpine-java:8_jdk
WORKDIR /tmp
RUN wget http://archive.apache.org/dist/maven/maven-3/3.6.1/binaries/apache-maven-3.6.1-bin.tar.gz
RUN tar -zxvf apache-maven-3.6.1-bin.tar.gz && rm apache-maven-3.6.1-bin.tar.gz
RUN mv apache-maven-3.6.1 /usr/lib/mvn
RUN chown -R root:root /usr/lib/mvn
RUN ln -s /usr/lib/mvn/bin/mvn /usr/bin/mvn
RUN wget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz
RUN tar -zxvf zookeeper-3.4.6.tar.gz
RUN mv zookeeper-3.4.6 /opt/zookeeper
RUN rm -rf zookeeper-3.4.6.tar.gz
RUN echo "export ZOOKEEPER_HOME=/opt/zookeeper" >>/etc/profile
RUN echo "export PATH=$PATH:$ZOOKEEPER_HOME/bin" >>/etc/profile
ADD conf/zoo.cfg /opt/zookeeper/conf/zoo.cfg
#RUN source /etc/profile
#RUN zkServer.sh start
RUN apk add --no-cache git npm nginx mariadb mariadb-client mariadb-server-utils pwgen
WORKDIR /opt
RUN git clone https://github.com/analysys/EasyScheduler.git
WORKDIR /opt/EasyScheduler
RUN mvn -U clean package assembly:assembly -Dmaven.test.skip=true
RUN mv /opt/EasyScheduler/target/escheduler-1.0.0-SNAPSHOT /opt/easyscheduler
WORKDIR /opt/EasyScheduler/escheduler-ui
RUN npm install
RUN npm audit fix
RUN npm run build
RUN mkdir -p /opt/escheduler/front/server
RUN cp -rfv dist/* /opt/escheduler/front/server
WORKDIR /
RUN rm -rf /opt/EasyScheduler
#configure mysql server https://github.com/yobasystems/alpine-mariadb/tree/master/alpine-mariadb-amd64
ADD conf/run.sh /scripts/run.sh
RUN mkdir /docker-entrypoint-initdb.d && \
mkdir /scripts/pre-exec.d && \
mkdir /scripts/pre-init.d && \
chmod -R 755 /scripts
RUN rm -rf /var/cache/apk/*
EXPOSE 8888
ENTRYPOINT ["/scripts/run.sh"]

31
conf/escheduler.conf

@ -1,31 +0,0 @@
server {
listen 8888;# 访问端口
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /opt/escheduler/front/server; # 静态文件目录
index index.html index.html;
}
location /escheduler {
proxy_pass http://127.0.0.1:12345; # 接口地址
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header x_real_ipP $remote_addr;
proxy_set_header remote_addr $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_connect_timeout 4s;
proxy_read_timeout 30s;
proxy_send_timeout 12s;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

310
conf/install.sh

@ -1,310 +0,0 @@
#!/bin/sh
workDir=`/opt/easyscheduler`
workDir=`cd ${workDir};pwd`
#To be compatible with MacOS and Linux
txt=""
if [[ "$OSTYPE" == "darwin"* ]]; then
# Mac OSX
txt="''"
elif [[ "$OSTYPE" == "linux-gnu" ]]; then
# linux
txt=""
elif [[ "$OSTYPE" == "cygwin" ]]; then
# POSIX compatibility layer and Linux environment emulation for Windows
echo "Easy Scheduler not support Windows operating system"
exit 1
elif [[ "$OSTYPE" == "msys" ]]; then
# Lightweight shell and GNU utilities compiled for Windows (part of MinGW)
echo "Easy Scheduler not support Windows operating system"
exit 1
elif [[ "$OSTYPE" == "win32" ]]; then
echo "Easy Scheduler not support Windows operating system"
exit 1
elif [[ "$OSTYPE" == "freebsd"* ]]; then
# ...
txt=""
else
# Unknown.
echo "Operating system unknown, please tell us(submit issue) for better service"
exit 1
fi
source ${workDir}/conf/config/run_config.conf
source ${workDir}/conf/config/install_config.conf
# mysql配置
# mysql 地址,端口
mysqlHost="127.0.0.1:3306"
# mysql 数据库名称
mysqlDb="easyscheduler"
# mysql 用户名
mysqlUserName="easyscheduler"
# mysql 密码
mysqlPassword="easyschedulereasyscheduler"
# conf/config/install_config.conf配置
# 安装路径,不要当前路径(pwd)一样
installPath="/opt/easyscheduler"
# 部署用户
deployUser="escheduler"
# zk集群
zkQuorum="192.168.xx.xx:2181,192.168.xx.xx:2181,192.168.xx.xx:2181"
# 安装hosts
ips="ark0,ark1,ark2,ark3,ark4"
# conf/config/run_config.conf配置
# 运行Master的机器
masters="ark0,ark1"
# 运行Worker的机器
workers="ark2,ark3,ark4"
# 运行Alert的机器
alertServer="ark3"
# 运行Api的机器
apiServers="ark1"
# alert配置
# 邮件协议
mailProtocol="SMTP"
# 邮件服务host
mailServerHost="smtp.exmail.qq.com"
# 邮件服务端口
mailServerPort="25"
# 发送人
mailSender="xxxxxxxxxx"
# 发送人密码
mailPassword="xxxxxxxxxx"
# 下载Excel路径
xlsFilePath="/tmp/xls"
# hadoop 配置
# 是否启动hdfs,如果启动则为true,需要配置以下hadoop相关参数;
# 不启动设置为false,如果为false,以下配置不需要修改
hdfsStartupSate="false"
# namenode地址,支持HA,需要将core-site.xml和hdfs-site.xml放到conf目录下
namenodeFs="hdfs://mycluster:8020"
# resourcemanager HA配置,如果是单resourcemanager,这里为空即可
yarnHaIps="192.168.xx.xx,192.168.xx.xx"
# 如果是单 resourcemanager,只需要配置一个主机名称,如果是resourcemanager HA,则默认配置就好
singleYarnIp="ark1"
# hdfs根路径,根路径的owner必须是部署用户
hdfsPath="/escheduler"
# common 配置
# 程序路径
programPath="/tmp/escheduler"
#下载路径
downloadPath="/tmp/escheduler/download"
# 任务执行路径
execPath="/tmp/escheduler/exec"
# SHELL环境变量路径
shellEnvPath="$installPath/conf/env/.escheduler_env.sh"
# Python换将变量路径
pythonEnvPath="$installPath/conf/env/escheduler_env.py"
# 资源文件的后缀
resSuffixs="txt,log,sh,conf,cfg,py,java,sql,hql,xml"
# 开发状态,如果是true,对于SHELL脚本可以在execPath目录下查看封装后的SHELL脚本,如果是false则执行完成直接删除
devState="true"
# zk 配置
# zk根目录
zkRoot="/escheduler"
# 用来记录挂掉机器的zk目录
zkDeadServers="/escheduler/dead-servers"
# masters目录
zkMasters="/escheduler/masters"
# workers目录
zkWorkers="/escheduler/workers"
# zk master分布式锁
mastersLock="/escheduler/lock/masters"
# zk worker分布式锁
workersLock="/escheduler/lock/workers"
# zk master容错分布式锁
mastersFailover="/escheduler/lock/failover/masters"
# zk worker容错分布式锁
workersFailover="/escheduler/lock/failover/masters"
# zk session 超时
zkSessionTimeout="300"
# zk 连接超时
zkConnectionTimeout="300"
# zk 重试间隔
zkRetrySleep="100"
# zk重试最大次数
zkRetryMaxtime="5"
# master 配置
# master执行线程最大数,流程实例的最大并行度
masterExecThreads="100"
# master任务执行线程最大数,每一个流程实例的最大并行度
masterExecTaskNum="20"
# master心跳间隔
masterHeartbeatInterval="10"
# master任务提交重试次数
masterTaskCommitRetryTimes="5"
# master任务提交重试时间间隔
masterTaskCommitInterval="100"
# master最大cpu平均负载,用来判断master是否还有执行能力
masterMaxCupLoadAvg="10"
# master预留内存,用来判断master是否还有执行能力
masterReservedMemory="1"
# worker 配置
# worker执行线程
workerExecThreads="100"
# worker心跳间隔
workerHeartbeatInterval="10"
# worker一次抓取任务数
workerFetchTaskNum="10"
# worker最大cpu平均负载,用来判断master是否还有执行能力
workerMaxCupLoadAvg="10"
# worker预留内存,用来判断master是否还有执行能力
workerReservedMemory="1"
# api 配置
# api 服务端口
apiServerPort="12345"
# api session 超时
apiServerSessionTimeout="7200"
# api 上下文路径
apiServerContextPath="/escheduler/"
# spring 最大文件大小
springMaxFileSize="1024MB"
# spring 最大请求文件大小
springMaxRequestSize="1024MB"
# api 最大post请求大小
apiMaxHttpPostSize="5000000"
# 1,替换文件
echo "1,替换文件"
sed -i ${txt} "s#spring.datasource.url.*#spring.datasource.url=jdbc:mysql://${mysqlHost}/${mysqlDb}?characterEncoding=UTF-8#g" conf/dao/data_source.properties
sed -i ${txt} "s#spring.datasource.username.*#spring.datasource.username=${mysqlUserName}#g" conf/dao/data_source.properties
sed -i ${txt} "s#spring.datasource.password.*#spring.datasource.password=${mysqlPassword}#g" conf/dao/data_source.properties
sed -i ${txt} "s#org.quartz.dataSource.myDs.URL.*#org.quartz.dataSource.myDs.URL=jdbc:mysql://${mysqlHost}/${mysqlDb}?characterEncoding=UTF-8#g" conf/quartz.properties
sed -i ${txt} "s#org.quartz.dataSource.myDs.user.*#org.quartz.dataSource.myDs.user=${mysqlUserName}#g" conf/quartz.properties
sed -i ${txt} "s#org.quartz.dataSource.myDs.password.*#org.quartz.dataSource.myDs.password=${mysqlPassword}#g" conf/quartz.properties
sed -i ${txt} "s#fs.defaultFS.*#fs.defaultFS=${namenodeFs}#g" conf/common/hadoop/hadoop.properties
sed -i ${txt} "s#yarn.resourcemanager.ha.rm.ids.*#yarn.resourcemanager.ha.rm.ids=${yarnHaIps}#g" conf/common/hadoop/hadoop.properties
sed -i ${txt} "s#yarn.application.status.address.*#yarn.application.status.address=http://${singleYarnIp}:8088/ws/v1/cluster/apps/%s#g" conf/common/hadoop/hadoop.properties
sed -i ${txt} "s#data.basedir.path.*#data.basedir.path=${programPath}#g" conf/common/common.properties
sed -i ${txt} "s#data.download.basedir.path.*#data.download.basedir.path=${downloadPath}#g" conf/common/common.properties
sed -i ${txt} "s#process.exec.basepath.*#process.exec.basepath=${execPath}#g" conf/common/common.properties
sed -i ${txt} "s#data.store2hdfs.basepath.*#data.store2hdfs.basepath=${hdfsPath}#g" conf/common/common.properties
sed -i ${txt} "s#hdfs.startup.state.*#hdfs.startup.state=${hdfsStartupSate}#g" conf/common/common.properties
sed -i ${txt} "s#escheduler.env.path.*#escheduler.env.path=${shellEnvPath}#g" conf/common/common.properties
sed -i ${txt} "s#escheduler.env.py.*#escheduler.env.py=${pythonEnvPath}#g" conf/common/common.properties
sed -i ${txt} "s#resource.view.suffixs.*#resource.view.suffixs=${resSuffixs}#g" conf/common/common.properties
sed -i ${txt} "s#development.state.*#development.state=${devState}#g" conf/common/common.properties
sed -i ${txt} "s#zookeeper.quorum.*#zookeeper.quorum=${zkQuorum}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.escheduler.root.*#zookeeper.escheduler.root=${zkRoot}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.escheduler.dead.servers.*#zookeeper.escheduler.dead.servers=${zkDeadServers}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.escheduler.masters.*#zookeeper.escheduler.masters=${zkMasters}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.escheduler.workers.*#zookeeper.escheduler.workers=${zkWorkers}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.escheduler.lock.masters.*#zookeeper.escheduler.lock.masters=${mastersLock}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.escheduler.lock.workers.*#zookeeper.escheduler.lock.workers=${workersLock}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.escheduler.lock.failover.masters.*#zookeeper.escheduler.lock.failover.masters=${mastersFailover}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.escheduler.lock.failover.workers.*#zookeeper.escheduler.lock.failover.workers=${workersFailover}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.session.timeout.*#zookeeper.session.timeout=${zkSessionTimeout}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.connection.timeout.*#zookeeper.connection.timeout=${zkConnectionTimeout}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.retry.sleep.*#zookeeper.retry.sleep=${zkRetrySleep}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.retry.maxtime.*#zookeeper.retry.maxtime=${zkRetryMaxtime}#g" conf/zookeeper.properties
sed -i ${txt} "s#master.exec.threads.*#master.exec.threads=${masterExecThreads}#g" conf/master.properties
sed -i ${txt} "s#master.exec.task.number.*#master.exec.task.number=${masterExecTaskNum}#g" conf/master.properties
sed -i ${txt} "s#master.heartbeat.interval.*#master.heartbeat.interval=${masterHeartbeatInterval}#g" conf/master.properties
sed -i ${txt} "s#master.task.commit.retryTimes.*#master.task.commit.retryTimes=${masterTaskCommitRetryTimes}#g" conf/master.properties
sed -i ${txt} "s#master.task.commit.interval.*#master.task.commit.interval=${masterTaskCommitInterval}#g" conf/master.properties
sed -i ${txt} "s#master.max.cpuload.avg.*#master.max.cpuload.avg=${masterMaxCupLoadAvg}#g" conf/master.properties
sed -i ${txt} "s#master.reserved.memory.*#master.reserved.memory=${masterReservedMemory}#g" conf/master.properties
sed -i ${txt} "s#worker.exec.threads.*#worker.exec.threads=${workerExecThreads}#g" conf/worker.properties
sed -i ${txt} "s#worker.heartbeat.interval.*#worker.heartbeat.interval=${workerHeartbeatInterval}#g" conf/worker.properties
sed -i ${txt} "s#worker.fetch.task.num.*#worker.fetch.task.num=${workerFetchTaskNum}#g" conf/worker.properties
sed -i ${txt} "s#worker.max.cpuload.avg.*#worker.max.cpuload.avg=${workerMaxCupLoadAvg}#g" conf/worker.properties
sed -i ${txt} "s#worker.reserved.memory.*#worker.reserved.memory=${workerReservedMemory}#g" conf/worker.properties
sed -i ${txt} "s#server.port.*#server.port=${apiServerPort}#g" conf/application.properties
sed -i ${txt} "s#server.session.timeout.*#server.session.timeout=${apiServerSessionTimeout}#g" conf/application.properties
sed -i ${txt} "s#server.context-path.*#server.context-path=${apiServerContextPath}#g" conf/application.properties
sed -i ${txt} "s#spring.http.multipart.max-file-size.*#spring.http.multipart.max-file-size=${springMaxFileSize}#g" conf/application.properties
sed -i ${txt} "s#spring.http.multipart.max-request-size.*#spring.http.multipart.max-request-size=${springMaxRequestSize}#g" conf/application.properties
sed -i ${txt} "s#server.max-http-post-size.*#server.max-http-post-size=${apiMaxHttpPostSize}#g" conf/application.properties
sed -i ${txt} "s#mail.protocol.*#mail.protocol=${mailProtocol}#g" conf/alert.properties
sed -i ${txt} "s#mail.server.host.*#mail.server.host=${mailServerHost}#g" conf/alert.properties
sed -i ${txt} "s#mail.server.port.*#mail.server.port=${mailServerPort}#g" conf/alert.properties
sed -i ${txt} "s#mail.sender.*#mail.sender=${mailSender}#g" conf/alert.properties
sed -i ${txt} "s#mail.passwd.*#mail.passwd=${mailPassword}#g" conf/alert.properties
sed -i ${txt} "s#xls.file.path.*#xls.file.path=${xlsFilePath}#g" conf/alert.properties
sed -i ${txt} "s#installPath.*#installPath=${installPath}#g" conf/config/install_config.conf
sed -i ${txt} "s#deployUser.*#deployUser=${deployUser}#g" conf/config/install_config.conf
sed -i ${txt} "s#ips.*#ips=${ips}#g" conf/config/install_config.conf
sed -i ${txt} "s#masters.*#masters=${masters}#g" conf/config/run_config.conf
sed -i ${txt} "s#workers.*#workers=${workers}#g" conf/config/run_config.conf
sed -i ${txt} "s#alertServer.*#alertServer=${alertServer}#g" conf/config/run_config.conf
sed -i ${txt} "s#apiServers.*#apiServers=${apiServers}#g" conf/config/run_config.conf

105
conf/run.sh

@ -1,105 +0,0 @@
#!/bin/sh
# execute any pre-init scripts
for i in /scripts/pre-init.d/*sh
do
if [ -e "${i}" ]; then
echo "[i] pre-init.d - processing $i"
. "${i}"
fi
done
if [ -d "/run/mysqld" ]; then
echo "[i] mysqld already present, skipping creation"
chown -R mysql:mysql /run/mysqld
else
echo "[i] mysqld not found, creating...."
mkdir -p /run/mysqld
chown -R mysql:mysql /run/mysqld
fi
if [ -d /var/lib/mysql/mysql ]; then
echo "[i] MySQL directory already present, skipping creation"
chown -R mysql:mysql /var/lib/mysql
else
echo "[i] MySQL data directory not found, creating initial DBs"
chown -R mysql:mysql /var/lib/mysql
mysql_install_db --user=mysql --ldata=/var/lib/mysql > /dev/null
if [ "$MYSQL_ROOT_PASSWORD" = "" ]; then
MYSQL_ROOT_PASSWORD=`pwgen 16 1`
echo "[i] MySQL root Password: $MYSQL_ROOT_PASSWORD"
fi
MYSQL_DATABASE="easyscheduler"
MYSQL_USER="easyscheduler"
MYSQL_PASSWORD="easyschedulereasyscheduler"
tfile=`mktemp`
if [ ! -f "$tfile" ]; then
return 1
fi
cat << EOF > $tfile
USE mysql;
FLUSH PRIVILEGES ;
GRANT ALL ON *.* TO 'root'@'%' identified by '$MYSQL_ROOT_PASSWORD' WITH GRANT OPTION ;
GRANT ALL ON *.* TO 'root'@'localhost' identified by '$MYSQL_ROOT_PASSWORD' WITH GRANT OPTION ;
SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${MYSQL_ROOT_PASSWORD}') ;
DROP DATABASE IF EXISTS test ;
FLUSH PRIVILEGES ;
EOF
if [ "$MYSQL_DATABASE" != "" ]; then
echo "[i] Creating database: $MYSQL_DATABASE"
echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` CHARACTER SET utf8 COLLATE utf8_general_ci;" >> $tfile
if [ "$MYSQL_USER" != "" ]; then
echo "[i] Creating user: $MYSQL_USER with password $MYSQL_PASSWORD"
echo "GRANT ALL ON \`$MYSQL_DATABASE\`.* to '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD';" >> $tfile
fi
fi
/usr/bin/mysqld --user=mysql --bootstrap --verbose=0 --skip-name-resolve --skip-networking=0 < $tfile
rm -f $tfile
for f in /docker-entrypoint-initdb.d/*; do
case "$f" in
*.sql) echo "$0: running $f"; /usr/bin/mysqld --user=mysql --bootstrap --verbose=0 --skip-name-resolve --skip-networking=0 < "$f"; echo ;;
*.sql.gz) echo "$0: running $f"; gunzip -c "$f" | /usr/bin/mysqld --user=mysql --bootstrap --verbose=0 --skip-name-resolve --skip-networking=0 < "$f"; echo ;;
*) echo "$0: ignoring or entrypoint initdb empty $f" ;;
esac
echo
done
echo
echo 'MySQL init process done. Ready for start up.'
echo
echo "exec /usr/bin/mysqld --user=mysql --console --skip-name-resolve --skip-networking=0" "$@"
fi
# execute any pre-exec scripts
for i in /scripts/pre-exec.d/*sh
do
if [ -e "${i}" ]; then
echo "[i] pre-exec.d - processing $i"
. ${i}
fi
done
mysql -ueasyscheduler -peasyschedulereasyscheduler --one-database easyscheduler -h127.0.0.1 < /opt/easyscheduler/sql/escheduler.sql
mysql -ueasyscheduler -peasyschedulereasyscheduler --one-database easyscheduler -h127.0.0.1 < /opt/easyscheduler/sql/quartz.sql
source /etc/profile
zkServer.sh start
cd /opt/easyscheduler
rm -rf /etc/nginx/conf.d/default.conf
sh ./bin/escheduler-daemon.sh start master-server
sh ./bin/escheduler-daemon.sh start worker-server
sh ./bin/escheduler-daemon.sh start api-server
sh ./bin/escheduler-daemon.sh start logger-server
sh ./bin/escheduler-daemon.sh start alert-server
nginx -c /etc/nginx/nginx.conf
exec /usr/bin/mysqld --user=mysql --console --skip-name-resolve --skip-networking=0 $@

30
conf/zoo.cfg

@ -1,30 +0,0 @@
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/tmp/zookeeper
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
dataDir=/opt/zookeeper/data
dataLogDir=/opt/zookeeper/logs

1
docs/zh_CN/SUMMARY.md

@ -8,6 +8,7 @@
* 后端部署文档 * 后端部署文档
* [准备工作](后端部署文档.md#1、准备工作) * [准备工作](后端部署文档.md#1、准备工作)
* [部署](后端部署文档.md#2、部署) * [部署](后端部署文档.md#2、部署)
* [快速上手](快速上手.md#快速上手)
* [系统使用手册](系统使用手册.md#使用手册) * [系统使用手册](系统使用手册.md#使用手册)
* [系统架构设计](系统架构设计.md#系统架构设计) * [系统架构设计](系统架构设计.md#系统架构设计)
* 前端开发文档 * 前端开发文档

BIN
docs/zh_CN/images/complement.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

BIN
docs/zh_CN/images/create-queue.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
docs/zh_CN/images/dag1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

BIN
docs/zh_CN/images/dag2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

BIN
docs/zh_CN/images/dag3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 KiB

BIN
docs/zh_CN/images/dag4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
docs/zh_CN/images/depend-node.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

BIN
docs/zh_CN/images/depend-node2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

BIN
docs/zh_CN/images/depend-node3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

BIN
docs/zh_CN/images/file-manage.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

BIN
docs/zh_CN/images/gant-pic.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

BIN
docs/zh_CN/images/hive_edit.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 46 KiB

BIN
docs/zh_CN/images/hive_edit2.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 47 KiB

BIN
docs/zh_CN/images/instance-detail.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

BIN
docs/zh_CN/images/instance-list.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

BIN
docs/zh_CN/images/master-jk.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

BIN
docs/zh_CN/images/mysql-jk.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

BIN
docs/zh_CN/images/mysql_edit.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 47 KiB

BIN
docs/zh_CN/images/postgressql_edit.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
docs/zh_CN/images/project.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

BIN
docs/zh_CN/images/run-work.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
docs/zh_CN/images/sql-node.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

BIN
docs/zh_CN/images/sql-node2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 KiB

BIN
docs/zh_CN/images/task-list.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

BIN
docs/zh_CN/images/task-log.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

BIN
docs/zh_CN/images/task-log2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

BIN
docs/zh_CN/images/time-schedule.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
docs/zh_CN/images/time-schedule2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
docs/zh_CN/images/worker-jk.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

BIN
docs/zh_CN/images/worker1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
docs/zh_CN/images/zk-jk.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

10
docs/zh_CN/后端部署文档.md

@ -4,7 +4,7 @@
## 1、准备工作 ## 1、准备工作
目前最新安装包版本是1.0.2,下载地址: [码云下载](https://gitee.com/easyscheduler/EasyScheduler/attach_files/) ,下载escheduler-backend-1.0.2.tar.gz(后端简称escheduler-backend),escheduler-ui-1.0.2.tar.gz(前端简称escheduler-ui) 目前最新安装包版本是1.0.3,下载地址: [码云下载](https://gitee.com/easyscheduler/EasyScheduler/attach_files/) ,下载escheduler-backend-1.0.3.tar.gz(后端简称escheduler-backend),escheduler-ui-1.0.3.tar.gz(前端简称escheduler-ui)
#### 准备一: 基础软件安装(必装项请自行安装) #### 准备一: 基础软件安装(必装项请自行安装)
@ -101,6 +101,12 @@ install.sh : 一键部署脚本
- 修改部署参数(根据自己服务器及业务情况): - 修改部署参数(根据自己服务器及业务情况):
- 修改 **install.sh**中的各参数,替换成自身业务所需的值 - 修改 **install.sh**中的各参数,替换成自身业务所需的值
- monitorServerState 开关变量,在1.0.3版本中增加,控制是否启动自启动脚本(监控master,worker状态,如果掉线会自动启动)
默认值为"false"表示不启动自启动脚本,如果需要启动改为"true"
- hdfsStartupSate 开关变量,控制是否启动hdfs
默认值为"false"表示不启动hdfs
如果需要启动改为"true",启动hdfs需要自行创建hdfs根路径,也就是install.sh中的 hdfsPath
- 如果使用hdfs相关功能,需要拷贝**hdfs-site.xml**和**core-site.xml**到conf目录下 - 如果使用hdfs相关功能,需要拷贝**hdfs-site.xml**和**core-site.xml**到conf目录下
@ -143,7 +149,7 @@ install.sh : 一键部署脚本
### 2.2 编译源码来部署 ### 2.2 编译源码来部署
将源码包release版本1.0.2下载后,解压进入根目录 将源码包release版本1.0.3下载后,解压进入根目录
* 执行编译命令: * 执行编译命令:

50
docs/zh_CN/快速上手.md

@ -0,0 +1,50 @@
## 快速上手
* 管理员用户登录
>地址:192.168.xx.xx:8888 用户名密码:admin/esheduler123
<p align="center">
<img src="https://analysys.github.io/easyscheduler_docs_cn/images/login.jpg" width="60%" />
</p>
* 创建队列
<p align="center">
<img src="https://analysys.github.io/easyscheduler_docs_cn/images/create-queue.png" width="60%" />
</p>
* 创建租户
<p align="center">
<img src="https://analysys.github.io/easyscheduler_docs_cn/images/addtenant.png" width="60%" />
</p>
* 创建普通用户
<p align="center">
<img src="https://analysys.github.io/easyscheduler_docs_cn/images/useredit2.png" width="60%" />
</p>
* 创建告警组
<p align="center">
<img src="https://analysys.github.io/easyscheduler_docs_cn/images/mail_edit.png" width="60%" />
</p>
* 使用普通用户登录
> 点击右上角用户名“退出”,重新使用普通用户登录。
* 项目管理->创建项目->点击项目名称
<p align="center">
<img src="https://analysys.github.io/easyscheduler_docs_cn/images/project.png" width="60%" />
</p>
* 点击工作流定义->创建工作流定义->上线流程定义
<p align="center">
<img src="https://analysys.github.io/easyscheduler_docs_cn/images/dag1.png" width="60%" />
</p>
* 运行流程定义->点击工作流实例->点击流程实例名称->双击任务节点->查看任务执行日志
<p align="center">
<img src="https://analysys.github.io/easyscheduler_docs_cn/images/task-log.png" width="60%" />
</p>

705
docs/zh_CN/系统使用手册.md

@ -1,213 +1,150 @@
# 使用手册 # 使用手册
## 登录 ## 快速上手
> 请参照[快速上手](快速上手.md)
- 输入http://192.168.xx.xx:8888/view/login/index.html 网址,输入用户名:admin,密码:escheduler123 登录 ## 操作指南
<p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/login.jpg" width="60%" /> - 管理员账号只能在权限上进行管理,不参与具体的业务,不能创建项目,不能对流程定义执行相关操作
</p> - 以下操作需要使用普通用户登录系统才能进行。
- 登录之后每个页面的右上角都有用户的身份标识。点击下拉箭头包含用户信息和退出两个按钮 ### 创建项目
- 点击“项目管理->创建项目”,输入项目名称,项目描述,点击“提交”,创建新的项目。
- 点击项目名称,进入项目首页。
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/logout.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/project.png" width="60%" />
</p> </p>
- 点击“用户信息”按钮,如下图: > 项目首页其中包含任务状态统计,流程状态统计、流程定义统计、队列统计、命令统计
- 任务状态统计:是指在指定时间范围内,统计任务实例中的待运行、失败、运行中、完成、成功的个数
- 流程状态统计:是指在指定时间范围内,统计流程实例中的待运行、失败、运行中、完成、成功的个数
- 流程定义统计:是统计该用户创建的流程定义及管理员授予该用户的流程定义
- 队列统计: worker执行队列统计,待执行的任务和待杀掉的任务个数
- 命令统计: 执行命令个数统计
### 创建工作流定义
- 进入项目首页,点击“工作流定义”,进入流程定义列表页。
- 点击“创建工作流”,创建新的流程定义。
- 拖拽“SHELL"节点到画布,新增一个Shell任务。
- 填写”节点名称“,”描述“,”脚本“字段。
- 选择“任务优先级”,级别高的任务在执行队列中会优先执行,相同优先级的任务按照先进先出的顺序执行。
- 超时告警, 填写”超时时长“,当任务执行时间超过**超时时长**可以告警并且超时失败。
- 填写"自定义参数",参考[自定义参数](#用户自定义参数)
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/userinfo.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/dag1.png" width="60%" />
</p> </p>
- 点击”修改”按钮,修改用户信息 - 增加节点之间执行的先后顺序: 点击”线条连接“;如图示,任务1和任务3并行执行,当任务1执行完,任务2、3会同时执行。
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/useredit.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/dag2.png" width="60%" />
</p> </p>
- 点击退出按钮则退出系统,返回登录页面 - 删除依赖关系: 点击箭头图标”拖动节点和选中项“,选中连接线,点击删除图标,删除节点间依赖关系。
## 安全中心
- 只有管理员才有安全中心,安全中心的主要功能是给管理员提供管理普通用户的功能。
- 管理员可以有多个,管理员是功能上的管理,不参与具体的业务。也就是说管理员是不能执行具体任务的。
### 租户管理
> 租户是Linux上的用户,用于作业的提交。
- 创建、编辑租户
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/addtenant.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/dag3.png" width="60%" />
</p> </p>
- 租户编码:租户编码是Linux上的用户,唯一,不能重复 - 点击”保存“,输入流程定义名称,流程定义描述,设置全局参数。
- 租户名称:租户的名称
- 队列:租户对应的YARN上的队列,在数据库 t_escheduler_queue 中设置
- 描述:租户的描述信息
### 用户管理
> 用户是EasyScheduler上的用户,用于EasyScheduler上的功能操作。
- 创建、编辑用户
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/useredit2.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/dag4.png" width="60%" />
</p> </p>
- 用户名称:用户的名称,唯一,不能重复 - 其他类型节点,请参考 [任务节点类型和参数设置](#任务节点类型和参数设置)
- 租户:设置该用户所属的租户
- 邮箱:输入用户的邮箱,用来邮件发送和任务告警
- 手机:输入用户的手机号
**注意:如果该用户切换了租户,则该用户所在租户下所有资源将复制到切换的新租户下**
### 执行流程定义
- **未上线状态的流程定义可以编辑,但是不可以运行**,所以先上线工作流
> 点击工作流定义,返回流程定义列表,点击”上线“图标,上线工作流定义。
- 授权 > "下线"工作流之前,要先将定时管理的定时下线,才能成功下线工作流定义
> 管理员可以对普通用户进行非其创建的项目、资源、数据源和UDF函数进行授权。因为项目、资源、数据源和UDF函数授权方式都是一样的,所以以项目授权为例介绍。
- 1.点击指定人的授权按钮,如下图:
- 点击”运行“,执行工作流。运行参数说明:
* 失败策略:**当某一个任务节点执行失败时,其他并行的任务节点需要执行的策略**。”继续“表示:其他任务节点正常执行,”结束“表示:终止所有正在执行的任务,并终止整个流程。
* 通知策略:当流程结束,根据流程状态发送流程执行信息通知邮件。
* 流程优先级:流程运行的优先级,分五个等级:最高(HIGHEST),高(HIGH),中(MEDIUM),低(LOW),最低(LOWEST)。级别高的流程在执行队列中会优先执行,相同优先级的流程按照先进先出的顺序执行。
* worker分组: 这个流程只能在指定的机器组里执行。默认是Default,可以在任一worker上执行。
* 通知组: 当流程结束,或者发生容错时,会发送流程信息邮件到通知组里所有成员。
* 收件人:输入邮箱后按回车键保存。当流程结束、发生容错时,会发送告警邮件到收件人列表。
* 抄送人:输入邮箱后按回车键保存。当流程结束、发生容错时,会抄送告警邮件到抄送人列表。
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/auth_user.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/run-work.png" width="60%" />
</p> </p>
- 2.选中项目按钮,进行项目授权 * 补数: 执行指定日期的工作流定义,可以选择补数时间范围(目前只支持针对连续的天进行补数),比如要补5月1号到5月10号的数据,如图示:
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/auth_project.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/complement.png" width="60%" />
</p> </p>
- 项目列表:是该用户未授权的项目 > 补数执行模式有**串行执行、并行执行**,串行模式下,补数会从5月1号到5月10号依次执行;并行模式下,会同时执行5月1号到5月10号的任务。
- 已选项目:是该用户已授权的项目。
- 特别注意:对于用户自己创建的项目,该用户拥有所有的权限。则项目列表和已选项目列表中不会体现。
### 告警组管理
> 告警组是告警用户抽象出来的组,使用告警组来管理用户。
- 新建、编辑邮件组
### 定时工作流定义
- 创建定时:"工作流定义->定时”
- 选择起止时间,在起止时间范围内,定时正常工作,超过范围,就不会再继续产生定时工作流实例了。
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/mail_edit.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/time-schedule.png" width="60%" />
</p> </p>
- 组名称:输入组的名称 - 添加一个每天凌晨5点执行一次的定时,如图示:
- 组类型:支持邮件/短信两种
- 备注:输入告警组的备注信息
- 管理用户
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/user_manager.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/time-schedule2.png" width="60%" />
</p> </p>
- 管理用户列表:是未添加到该组的用户列表 - 定时上线,**新创建的定时是下线状态,需要点击“定时管理->上线”,定时才能正常工作**。
- 已选管理用户:是已添加到该组的用户列表
### 查看流程实例
> 点击“工作流实例”,查看流程实例列表。
### 服务管理 > 点击工作流名称,查看任务执行状态。
> 服务管理是对EasyScheduler的Master、Worker的任务监控
#### Master
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/master.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/instance-detail.png" width="60%" />
</p> </p>
#### Worker > 双击任务节点,点击“查看日志”,查看任务执行日志。
<p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/worker.png" width="60%" />
</p>
## 资源中心
> 资源中心主要分为文件管理和UDF函数管理。
文件管理:主要是用户的程序,脚本和配置文件需要上传到HDFS进行统一管理
UDF函数管理:对用户创建的UDF进行管理
### 文件管理
#### 创建文件
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/file_create.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/task-log.png" width="60%" />
</p> </p>
- 文件格式支持以下几种类型:txt、log、sh、conf、cfg、py、java、sql、xml、hql > 对工作流实例的操作:
#### 上传文件
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/file_upload.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/instance-list.png" width="60%" />
</p> </p>
- 文件名:输入文件的名称 * 编辑:可以对已经终止的流程进行编辑,编辑后保存的时候,可以选择是否更新到流程定义。
- 描述:输入文件的描述信息 * 重跑:可以对已经终止的流程进行重新执行。
- 上传文件:点击上传按钮进行上传,将文件拖拽到上传区域,文件名会自动以上传的文件名称补全 * 恢复失败:针对失败的流程,可以执行恢复失败操作,从失败的节点开始执行。
* 停止:对正在运行的流程进行**停止**操作,后台会先对worker进程`kill`,再执行`kill -9`操作
* 暂停:可以对正在运行的流程进行**暂停**操作,系统状态变为**等待执行**,会等待正在执行的任务结束,暂停下一个要执行的任务。
#### 文件查看 * 恢复暂停:可以对暂停的流程恢复,直接从**暂停的节点**开始运行
* 删除:删除流程实例及流程实例下的任务实例
> 对可查看的文件类型,点击 文件名称 可以查看文件详情 * 甘特图:Gantt图纵轴是某个流程实例下的任务实例的拓扑排序,横轴是任务实例的运行时间,如图示:
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/file_detail.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/gant-pic.png" width="60%" />
</p> </p>
#### 下载文件 ### 查看任务实例
> 点击“任务实例”,进入任务列表页,查询任务执行情况
> 可以在 文件详情 中点击右上角下载按钮下载文件,或者在文件列表后的下载按钮下载文件
#### 文件重命名
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/file_rename.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/task-list.png" width="60%" />
</p> </p>
#### 删除 > 点击操作列中的“查看日志”,可以查看任务执行的日志情况。
- 文件列表,点击 删除 按钮,删除文件
### UDF管理
#### 资源管理
> 资源管理和文件管理功能类似,不同之处是资源管理是上传的UDF函数,文件管理上传的是用户程序,脚本及配置文件
#### 函数管理
##### 创建、编辑UDF函数
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/udf_edit.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/task-log2.png" width="60%" />
</p> </p>
目前只支持HIVE的临时UDF函数 ### 创建数据源
> 数据源中心支持MySQL、POSTGRESQL、HIVE及Spark等数据源
- UDF函数名称:输入UDF函数时的名称
- 包名类名:输入UDF函数的全路径
- 参数:用来标注函数的输入参数
- 数据库名:预留字段,用于创建永久UDF函数
- UDF资源:设置创建的UDF对应的资源文件
## 数据源中心 #### 创建、编辑MySQL数据源
> 数据源中心支持MySQL、POSTGRESQL、HIVE及Spark数据源 - 点击“数据源中心->创建数据源”,根据需求创建不同类型的数据源。
### 创建、编辑MySQL数据源
<p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/mysql_edit.png" width="60%" />
</p>
- 数据源:选择MYSQL - 数据源:选择MYSQL
- 数据源名称:输入数据源的名称 - 数据源名称:输入数据源的名称
@ -219,12 +156,14 @@ UDF函数管理:对用户创建的UDF进行管理
- 数据库名:输入连接MySQL的数据库名称 - 数据库名:输入连接MySQL的数据库名称
- Jdbc连接参数:用于MySQL连接的参数设置,以JSON形式填写 - Jdbc连接参数:用于MySQL连接的参数设置,以JSON形式填写
### 创建、编辑POSTGRESQL数据源
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/postgresql_edit.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/mysql_edit.png" width="60%" />
</p> </p>
> 点击“测试连接”,测试数据源是否可以连接成功。
#### 创建、编辑POSTGRESQL数据源
- 数据源:选择POSTGRESQL - 数据源:选择POSTGRESQL
- 数据源名称:输入数据源的名称 - 数据源名称:输入数据源的名称
- 描述:输入数据源的描述 - 描述:输入数据源的描述
@ -235,13 +174,16 @@ UDF函数管理:对用户创建的UDF进行管理
- 数据库名:输入连接POSTGRESQL的数据库名称 - 数据库名:输入连接POSTGRESQL的数据库名称
- Jdbc连接参数:用于POSTGRESQL连接的参数设置,以JSON形式填写 - Jdbc连接参数:用于POSTGRESQL连接的参数设置,以JSON形式填写
<p align="center">
<img src="https://analysys.github.io/easyscheduler_docs_cn/images/postgresql_edit.png" width="60%" />
</p>
### 创建、编辑HIVE数据源 #### 创建、编辑HIVE数据源
1.使用HiveServer2方式连接 1.使用HiveServer2方式连接
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/hive_edit.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/hive_edit.png" width="60%" />
</p> </p>
- 数据源:选择HIVE - 数据源:选择HIVE
@ -257,24 +199,14 @@ UDF函数管理:对用户创建的UDF进行管理
2.使用HiveServer2 HA Zookeeper方式连接 2.使用HiveServer2 HA Zookeeper方式连接
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/hive_edit2.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/hive_edit2.png" width="60%" />
</p> </p>
- 数据源:选择HIVE
- 数据源名称:输入数据源的名称
- 描述:输入数据源的描述
- IP/主机名:输入连接Zookeeper的集群
- 端口:输入连接Zookeeper的端口
- 用户名:设置连接HIVE的用户名
- 密码:设置连接HIVE的密码
- 数据库名:输入连接HIVE的数据库名称
- Jdbc连接参数:用于Zookeeper连接的参数设置,以JSON形式填写
### 创建、编辑Spark数据源 #### 创建、编辑Spark数据源
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/spark_datesource.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/spark_datesource.png" width="60%" />
</p> </p>
- 数据源:选择Spark - 数据源:选择Spark
@ -287,361 +219,383 @@ UDF函数管理:对用户创建的UDF进行管理
- 数据库名:输入连接Spark的数据库名称 - 数据库名:输入连接Spark的数据库名称
- Jdbc连接参数:用于Spark连接的参数设置,以JSON形式填写 - Jdbc连接参数:用于Spark连接的参数设置,以JSON形式填写
## 首页 ### 上传资源
- 上传资源文件和udf函数,所有上传的文件和资源都会被存储到hdfs上,所以需要以下配置项:
```
conf/common/common.properties
-- hdfs.startup.state=true
conf/common/hadoop.properties
-- fs.defaultFS=hdfs://xxxx:8020
-- yarn.resourcemanager.ha.rm.ids=192.168.xx.xx,192.168.xx.xx
-- yarn.application.status.address=http://xxxx:8088/ws/v1/cluster/apps/%s
```
#### 文件管理
> 是对各种资源文件的管理,包括创建基本的txt/log/sh/conf等文件、上传jar包等各种类型文件,以及编辑、下载、删除等操作。
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/project_index.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/file-manage.png" width="60%" />
</p> </p>
> 首页是对所有项目在指定时间范围内的任务状态、流程状态和流程定义的统计。 * 创建文件
> 文件格式支持以下几种类型:txt、log、sh、conf、cfg、py、java、sql、xml、hql
首页和项目首页的主要区别在于:
- 首页中的图表是没有链接的,项目首页中图表是有链接的 <p align="center">
- 首页统计的是所有的项目,项目首页统计的是某一个项目 <img src="https://analysys.github.io/easyscheduler_docs_cn/images/file_create.png" width="60%" />
</p>
## 项目管理 * 上传文件
> 项目是调度对用户流程定义DAG分组的一个抽象
### 创建、编辑项目 > 上传文件:点击上传按钮进行上传,将文件拖拽到上传区域,文件名会自动以上传的文件名称补全
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/project_edit.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/file_upload.png" width="60%" />
</p> </p>
- 项目名称:输入项目的名称
- 描述:输入项目的描述
* 文件查看
### 项目首页 > 对可查看的文件类型,点击 文件名称 可以查看文件详情
> 点击项目列表中的项目名称,可以跳转到指定的项目首页,如下图:
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/project_index.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/file_detail.png" width="60%" />
</p> </p>
- 项目首页其中包含四个部分,任务状态统计,流程状态统计、流程定义统计及统计的时间范围 * 下载文件
- 任务状态统计:是指在指定时间范围内,统计任务实例中的待运行、失败、运行中、完成、成功的个数
- 流程状态统计:是指在指定时间范围内,统计流程实例中的待运行、失败、运行中、完成、成功的个数 > 可以在 文件详情 中点击右上角下载按钮下载文件,或者在文件列表后的下载按钮下载文件
- 流程定义统计:是统计该用户创建的流程定义及管理员授予该用户的流程定义
* 文件重命名
<p align="center">
<img src="https://analysys.github.io/easyscheduler_docs_cn/images/file_rename.png" width="60%" />
</p>
注意:可以点击图,或者数量跳转到相应的任务实例,流程实例和流程定义列表 #### 删除
> 文件列表->点击"删除"按钮,删除指定文件
### 工作流 #### 资源管理
> 资源管理和文件管理功能类似,不同之处是资源管理是上传的UDF函数,文件管理上传的是用户程序,脚本及配置文件
> 工作流分为流程定义、流程实例和任务实例三个功能模块 * 上传udf资源
> 和上传文件相同。
- 流程定义:是可视化拖拽成的DAG的统称,它是静态的,没有状态 #### 函数管理
- 流程实例:对流程定义的每次实例化会生成一个流程实例,是动态的,是有状态的
- 任务实例:流程实例DAG中每个Task称为任务实例,是动态的,是有状态的
* 创建udf函数
> 点击“创建UDF函数”,输入udf函数参数,选择udf资源,点击“提交”,创建udf函数。
#### 流程定义 > 目前只支持HIVE的临时UDF函数
##### 创建工作流 - UDF函数名称:输入UDF函数时的名称
- 包名类名:输入UDF函数的全路径
- 参数:用来标注函数的输入参数
- 数据库名:预留字段,用于创建永久UDF函数
- UDF资源:设置创建的UDF对应的资源文件
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/definition_create.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/udf_edit.png" width="60%" />
</p> </p>
- 左侧工具栏 => 是目前调度支持的任务类型,当前调度支持SHELL、子流程、存储过程、SQL、MR、Spark和Python七种任务类型 ## 安全中心(权限系统)
- 右上角图标 => 分别是拖动节点和选中项、选择线条连线、删除选中的线或节点、全屏和流程定义保持,其主要功能是DAG的绘制所用
##### 创建 SHELL节点 - 安全中心是只有管理员账户才有权限的功能,有队列管理、租户管理、用户管理、告警组管理、worker分组、令牌管理等功能,还可以对资源、数据源、项目等授权
- 管理员登录,默认用户名密码:admin/esheduler123
> 拖动工具栏中的![PNG](https://analysys.github.io/EasyScheduler/zh_CN/images/toolbar_SHELL.png)任务节点到画板中,双击任务节点,如下图:
### 创建队列
- 队列是在执行spark、mapreduce等程序,需要用到“队列”参数时使用的。
- “安全中心”->“队列管理”->“创建队列”
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/shell_edit.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/create-queue.png" width="60%" />
</p> </p>
- 节点名称:一个流程定义中的节点名称是唯一的
- 运行标志:标识这个节点是否能正常调度
- 描述信息:描述该节点的功能
- 失败重试次数:任务失败重新提交的次数,支持下拉和手填
- 失败重试间隔:任务失败重新提交任务的时间间隔,支持下拉和手填
- 脚本:用户开发的SHELL程序
- 资源:是指脚本中需要调用的资源文件列表
- 自定义参数:是SHELL局部的用户自定义参数,会替换脚本中以${变量}的内容
##### 创建 子流程 节点 ### 添加租户
- 租户对应的是Linux的用户,用于worker提交作业所使用的用户。如果linux没有这个用户,worker会在执行脚本的时候创建这个用户。
- 租户编码:**租户编码是Linux上的用户,唯一,不能重复**
> 拖动工具栏中的![PNG](https://analysys.github.io/EasyScheduler/zh_CN/images/toolbar_SUB_PROCESS.png)任务节点到画板中,双击任务节点,如下图: <p align="center">
<img src="https://analysys.github.io/easyscheduler_docs_cn/images/addtenant.png" width="60%" />
</p>
### 创建普通用户
- 用户分为**管理员用户**和**普通用户**
* 管理员只有**授权和用户管理**等权限,没有**创建项目和流程定义**的操作的权限
* 普通用户可以**创建项目和对流程定义的创建,编辑,执行**等操作。
* 注意:**如果该用户切换了租户,则该用户所在租户下所有资源将复制到切换的新租户下**
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/subprocess_edit.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/useredit2.png" width="60%" />
</p> </p>
- 节点名称:一个流程定义中的节点名称是唯一的 ### 创建告警组
- 运行标志:标识这个节点是否能正常调度 * 告警组是在启动时设置的参数,在流程结束以后会将流程的状态和其他信息以邮件形式发送给告警组。
- 描述信息:描述该节点的功能 - 新建、编辑告警组
- 子节点:是选择子流程的流程定义,右上角进入该子节点可以跳转到所选子流程的流程定义
##### 创建 存储过程 节点 <p align="center">
<img src="https://analysys.github.io/easyscheduler_docs_cn/images/mail_edit.png" width="60%" />
</p>
> 拖动工具栏中的![PNG](https://analysys.github.io/EasyScheduler/zh_CN/images/toolbar_PROCEDURE.png)任务节点到画板中,双击任务节点,如下图: ### 创建worker分组
- worker分组,提供了一种让任务在指定的worker上运行的机制。管理员设置worker分组,每个任务节点可以设置该任务运行的worker分组,如果任务指定的分组被删除或者没有指定分组,则该任务会在流程实例指定的worker上运行。
- worker分组内多个ip地址(**不能写别名**),以**英文逗号**分隔
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/procedure_edit.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/worker1.png" width="60%" />
</p> </p>
- 节点名称:一个流程定义中的节点名称是唯一的 ### 令牌管理
- 运行标志:标识这个节点是否能正常调度 - 由于后端接口有登录检查,令牌管理,提供了一种可以通过调用接口的方式对系统进行各种操作。
- 描述信息:描述该节点的功能 - 调用示例:
- 失败重试次数:任务失败重新提交的次数,支持下拉和手填
- 失败重试间隔:任务失败重新提交任务的时间间隔,支持下拉和手填
- 数据源:存储过程的数据源类型支持MySQL和POSTGRESQL两种,选择对应的数据源
- 方法:是存储过程的方法名称
- 自定义参数:存储过程的自定义参数类型支持IN、OUT两种,数据类型支持VARCHAR、INTEGER、LONG、FLOAT、DOUBLE、DATE、TIME、TIMESTAMP、BOOLEAN九种数据类型
```令牌调用示例
/**
* test token
*/
public void doPOSTParam()throws Exception{
// create HttpClient
CloseableHttpClient httpclient = HttpClients.createDefault();
// create http post request
HttpPost httpPost = new HttpPost("http://127.0.0.1:12345/escheduler/projects/create");
httpPost.setHeader("token", "123");
// set parameters
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
parameters.add(new BasicNameValuePair("projectName", "qzw"));
parameters.add(new BasicNameValuePair("desc", "qzw"));
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters);
httpPost.setEntity(formEntity);
CloseableHttpResponse response = null;
try {
// execute
response = httpclient.execute(httpPost);
// eponse status code 200
if (response.getStatusLine().getStatusCode() == 200) {
String content = EntityUtils.toString(response.getEntity(), "UTF-8");
System.out.println(content);
}
} finally {
if (response != null) {
response.close();
}
httpclient.close();
}
}
```
##### 创建 SQL 节点 ### 授予权限
- 授予权限包括项目权限,资源权限,数据源权限,UDF函数权限。
> 管理员可以对普通用户进行非其创建的项目、资源、数据源和UDF函数进行授权。因为项目、资源、数据源和UDF函数授权方式都是一样的,所以以项目授权为例介绍。
> 拖动工具栏中的![PNG](https://analysys.github.io/EasyScheduler/zh_CN/images/toolbar_SQL.png)任务节点到画板中,双击任务节点,如下图: > 注意:**对于用户自己创建的项目,该用户拥有所有的权限。则项目列表和已选项目列表中不会体现**
- 1.点击指定人的授权按钮,如下图:
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/sql_edit.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/auth_user.png" width="60%" />
</p> </p>
- 节点名称:一个流程定义中的节点名称是唯一的 - 2.选中项目按钮,进行项目授权
- 运行标志:标识这个节点是否能正常调度
- 描述信息:描述该节点的功能
- 失败重试次数:任务失败重新提交的次数,支持下拉和手填
- 失败重试间隔:任务失败重新提交任务的时间间隔,支持下拉和手填
- 数据源:SQL数据源支持MySQL、POSTGRESQL、HIVE和Spark四中数据源类型,选择对应的数据源
- sql类型:支持查询和非查询两种,查询是select类型的查询,是有结果集返回的,可以指定邮件通知为表格、附件或表格附件三种模板。非查询是没有结果集返回的,是针对update、delete、insert三种类型的操作
- sql参数:输入参数格式为key1=value1;key2=value2…
- sql语句:SQL语句
- UDF函数:对于HIVE类型的数据源,可以引用资源中心中创建的UDF函数,其他类型的数据源暂不支持UDF函数
- 自定义参数:SQL任务类型自定义参数类型和数据类型同存储过程任务类型一样。区别在于SQL任务类型自定义参数会替换sql语句中${变量},而存储过程是自定义参数顺序的给方法设置值
##### 创建 MR 节点
> 拖动工具栏中的![PNG](https://analysys.github.io/EasyScheduler/zh_CN/images/toolbar_MR.png)任务节点到画板中,双击任务节点,如下图:
(1) JAVA程序
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/mr_java.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/auth_project.png" width="60%" />
</p> </p>
- 节点名称:一个流程定义中的节点名称是唯一的
- 运行标志:标识这个节点是否能正常调度
- 描述信息:描述该节点的功能
- 失败重试次数:任务失败重新提交的次数,支持下拉和手填
- 失败重试间隔:任务失败重新提交任务的时间间隔,支持下拉和手填
- 主函数的class:是MR程序的入口Main Class的全路径
- 程序类型:选择JAVA语言
- 主jar包:是MR的jar包
- 命令行参数:是设置MR程序的输入参数,支持自定义参数变量的替换
- 其他参数:支持 –D、-files、-libjars、-archives格式
- 资源: 如果其他参数中引用了资源文件,需要在资源中选择指定
- 自定义参数:是MR局部的用户自定义参数,会替换脚本中以${变量}的内容
(2) Python程序 ## 监控中心
### 服务管理
- 服务管理主要是对系统中的各个服务的健康状况和基本信息的监控和显示
#### master监控
- 主要是master的相关信息。
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/mr_edit.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/master-jk.png" width="60%" />
</p> </p>
- 节点名称:一个流程定义中的节点名称是唯一的 #### worker监控
- 运行标志:标识这个节点是否能正常调度 - 主要是worker的相关信息。
- 描述信息:描述该节点的功能
- 失败重试次数:任务失败重新提交的次数,支持下拉和手填
- 失败重试间隔:任务失败重新提交任务的时间间隔,支持下拉和手填
- 程序类型:选择Python语言
- 主jar包:是运行MR的Python jar包
- 其他参数:支持 –D、-mapper、-reducer、-input -output格式,这里可以设置用户自定义参数的输入,比如:
- -mapper "mapper.py 1" -file mapper.py -reducer reducer.py -file reducer.py –input /journey/words.txt -output /journey/out/mr/${currentTimeMillis}
- 其中 -mapper 后的 mapper.py 1是两个参数,第一个参数是mapper.py,第二个参数是1
- 资源: 如果其他参数中引用了资源文件,需要在资源中选择指定
- 自定义参数:是MR局部的用户自定义参数,会替换脚本中以${变量}的内容
##### 创建 Spark 节点 <p align="center">
<img src="https://analysys.github.io/easyscheduler_docs_cn/images/worker-jk.png" width="60%" />
</p>
> 拖动工具栏中的![PNG](https://analysys.github.io/EasyScheduler/zh_CN/images/toolbar_SPARK.png)任务节点到画板中,双击任务节点,如下图: #### Zookeeper监控
- 主要是zookpeeper中各个worker和master的相关配置信息。
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/spark_edit.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/zk-jk.png" width="60%" />
</p> </p>
- 节点名称:一个流程定义中的节点名称是唯一的 #### Mysql监控
- 运行标志:标识这个节点是否能正常调度 - 主要是mysql的健康状况
- 描述信息:描述该节点的功能
- 失败重试次数:任务失败重新提交的次数,支持下拉和手填
- 失败重试间隔:任务失败重新提交任务的时间间隔,支持下拉和手填
- 程序类型:支持JAVA、Scala和Python三种语言
- 主函数的class:是Spark程序的入口Main Class的全路径
- 主jar包:是Spark的jar包
- 部署方式:支持yarn-cluster、yarn-client、和local三种模式
- Driver内核数:可以设置Driver内核数及内存数
- Executor数量:可以设置Executor数量、Executor内存数和Executor内核数
- 命令行参数:是设置Spark程序的输入参数,支持自定义参数变量的替换。
- 其他参数:支持 --jars、--files、--archives、--conf格式
- 资源:如果其他参数中引用了资源文件,需要在资源中选择指定
- 自定义参数:是MR局部的用户自定义参数,会替换脚本中以${变量}的内容
注意:JAVA和Scala只是用来标识,没有区别,如果是Python开发的Spark则没有主函数的class,其他都是一样 <p align="center">
<img src="https://analysys.github.io/easyscheduler_docs_cn/images/mysql-jk.png" width="60%" />
</p>
##### 创建 Python 节点 ## 任务节点类型和参数设置
> 拖动工具栏中的![PNG](https://analysys.github.io/EasyScheduler/zh_CN/images/toolbar_PYTHON.png)任务节点到画板中,双击任务节点,如下图: ### Shell节点
- shell节点,在worker执行的时候,会生成一个临时shell脚本,使用租户同名的linux用户执行这个脚本。
> 拖动工具栏中的![PNG](https://analysys.github.io/easyscheduler_docs_cn/images/toolbar_SHELL.png)任务节点到画板中,双击任务节点,如下图:
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/python_edit.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/shell_edit.png" width="60%" />
</p> </p>
- 节点名称:一个流程定义中的节点名称是唯一的 - 节点名称:一个流程定义中的节点名称是唯一的
- 运行标志:标识这个节点是否能正常调度 - 运行标志:标识这个节点是否能正常调度,如果不需要执行,可以打开禁止执行开关。
- 描述信息:描述该节点的功能 - 描述信息:描述该节点的功能
- 失败重试次数:任务失败重新提交的次数,支持下拉和手填 - 失败重试次数:任务失败重新提交的次数,支持下拉和手填
- 失败重试间隔:任务失败重新提交任务的时间间隔,支持下拉和手填 - 失败重试间隔:任务失败重新提交任务的时间间隔,支持下拉和手填
- 脚本:用户开发的Python程序 - 脚本:用户开发的SHELL程序
- 资源:是指脚本中需要调用的资源文件列表 - 资源:是指脚本中需要调用的资源文件列表
- 自定义参数:是Python局部的用户自定义参数,会替换脚本中以${变量}的内容 - 自定义参数:是SHELL局部的用户自定义参数,会替换脚本中以${变量}的内容
##### 创建 依赖 节点
> 任务依赖分为水平依赖和垂直依赖
- 水平依赖就是指DAG图的有向依赖,是同一个流程实例任务节点的前驱,后继之间的依赖关系
- 垂直依赖是流程实例之间的任务依赖,基于定时的依赖。
> 拖动工具栏中的![PNG](https://analysys.github.io/EasyScheduler/zh_CN/images/toolbar_DEPENDENT.png)任务节点到画板中,双击任务节点,如下图: ### 子流程节点
- 子流程节点,就是把外部的某个工作流定义当做自己的一个任务节点去执行。
> 拖动工具栏中的![PNG](https://analysys.github.io/easyscheduler_docs_cn/images/toolbar_SUB_PROCESS.png)任务节点到画板中,双击任务节点,如下图:
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/dependent_edit.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/subprocess_edit.png" width="60%" />
</p> </p>
- 节点名称:一个流程定义中的节点名称是唯一的 - 节点名称:一个流程定义中的节点名称是唯一的
- 运行标志:标识这个节点是否能正常调度 - 运行标志:标识这个节点是否能正常调度
- 描述信息:描述该节点的功能 - 描述信息:描述该节点的功能
- 失败重试次数:任务失败重新提交的次数,支持下拉和手填 - 子节点:是选择子流程的流程定义,右上角进入该子节点可以跳转到所选子流程的流程定义
- 失败重试间隔:任务失败重新提交任务的时间间隔,支持下拉和手填
- 任务依赖:增加依赖条件,选择依赖流程定义、节点名称(默认为全部节点)、依赖周期、依赖时间点
<p align="center"> ### 依赖(DEPENDENT)节点
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/dependent_edit3.png" width="60%" /> - 依赖节点,就是**依赖检查节点**。比如A流程依赖昨天的B流程执行成功,依赖节点会去检查B流程在昨天是否有执行成功的实例。
</p>
- 选择多个依赖条件之间的关系:或、且 > 拖动工具栏中的![PNG](https://analysys.github.io/easyscheduler_docs_cn/images/toolbar_DEPENDENT.png)任务节点到画板中,双击任务节点,如下图:
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/dependent_edit4.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/dependent_edit.png" width="60%" />
</p> </p>
#### 流程实例列表 > 依赖节点提供了逻辑判断功能,比如检查昨天的B流程是否成功,或者C流程是否执行成功。
> 流程实例列表页是可以显示所有本项目下所有流程实例的列表,并有对流程实例进行名称、状态、时间等字段的筛选功能。
> 通过列表页可以直接对某一个流程实例进行编辑、重跑、恢复失败、暂停、停止、恢复暂停、删除、查看甘特图等操作.
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/process-list.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/depend-node.png" width="80%" />
</p> </p>
- 编辑功能: 对已经完成的流程实例,点击编辑按钮,可以对其编辑,如图 > 例如,A流程为周报任务,B、C流程为天任务,A任务需要B、C任务在上周的每一天都执行成功,如图示
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/process-list2.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/depend-node2.png" width="80%" />
</p> </p>
- 查看流程实例运行变量 > 假如,周报A同时还需要自身在上周二执行成功:
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/variable_view.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/depend-node3.png" width="80%" />
</p> </p>
- 点击隐藏按钮,查看流程实例运行变量。如下图: ### 存储过程节点
- 根据选择的数据源,执行存储过程。
> 拖动工具栏中的![PNG](https://analysys.github.io/easyscheduler_docs_cn/images/toolbar_PROCEDURE.png)任务节点到画板中,双击任务节点,如下图:
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/variable_view2.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/procedure_edit.png" width="60%" />
</p> </p>
- 点击变量是对变量的复制 - 数据源:存储过程的数据源类型支持MySQL和POSTGRESQL两种,选择对应的数据源
- 方法:是存储过程的方法名称
- 点击"重跑",可以对已经完成的流程实例进行重新运行操作,如图: - 自定义参数:存储过程的自定义参数类型支持IN、OUT两种,数据类型支持VARCHAR、INTEGER、LONG、FLOAT、DOUBLE、DATE、TIME、TIMESTAMP、BOOLEAN九种数据类型
### SQL节点
- 执行非查询SQL功能
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/process-list3.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/sql-node.png" width="60%" />
</p> </p>
- 点击"恢复失败", 可以对失败的流程进行恢复,直接从失败的任务节点开始运行。如图: - 执行查询SQL功能,可以选择通过表格和附件形式发送邮件到指定的收件人。
> 拖动工具栏中的![PNG](https://analysys.github.io/easyscheduler_docs_cn/images/toolbar_SQL.png)任务节点到画板中,双击任务节点,如下图:
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/process-list4.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/sql-node2.png" width="60%" />
</p> </p>
- 点击"暂停", 可以对正在运行的流程进行**暂停**操作,如图: - 数据源:选择对应的数据源
- sql类型:支持查询和非查询两种,查询是select类型的查询,是有结果集返回的,可以指定邮件通知为表格、附件或表格附件三种模板。非查询是没有结果集返回的,是针对update、delete、insert三种类型的操作
- sql参数:输入参数格式为key1=value1;key2=value2…
- sql语句:SQL语句
- UDF函数:对于HIVE类型的数据源,可以引用资源中心中创建的UDF函数,其他类型的数据源暂不支持UDF函数
- 自定义参数:SQL任务类型,而存储过程是自定义参数顺序的给方法设置值自定义参数类型和数据类型同存储过程任务类型一样。区别在于SQL任务类型自定义参数会替换sql语句中${变量}
<p align="center"> ### SPARK节点
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/process-list-pause.png" width="60%" /> - 通过SPARK节点,可以直接直接执行SPARK程序,对于spark节点,worker会使用`spark-submit`方式提交任务
</p>
- 点击"停止",可以对正在运行的流程进行**停止**操作,如图: > 拖动工具栏中的![PNG](https://analysys.github.io/easyscheduler_docs_cn/images/toolbar_SPARK.png)任务节点到画板中,双击任务节点,如下图:
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/process-list-stop.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/spark_edit.png" width="60%" />
</p> </p>
- 点击"恢复暂停",可以对暂停的流程恢复,直接从**暂停的节点**开始运行,如图: - 程序类型:支持JAVA、Scala和Python三种语言
- 主函数的class:是Spark程序的入口Main Class的全路径
<p align="center"> - 主jar包:是Spark的jar包
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/process-list-recovery-pause.png" width="60%" /> - 部署方式:支持yarn-cluster、yarn-client、和local三种模式
</p> - Driver内核数:可以设置Driver内核数及内存数
- Executor数量:可以设置Executor数量、Executor内存数和Executor内核数
- 命令行参数:是设置Spark程序的输入参数,支持自定义参数变量的替换。
- 其他参数:支持 --jars、--files、--archives、--conf格式
- 资源:如果其他参数中引用了资源文件,需要在资源中选择指定
- 自定义参数:是MR局部的用户自定义参数,会替换脚本中以${变量}的内容
- 删除 注意:JAVA和Scala只是用来标识,没有区别,如果是Python开发的Spark则没有主函数的class,其他都是一样
> 删除流程实例及流程实例下的任务实例
- Gantt ### MapReduce(MR)节点
- 使用MR节点,可以直接执行MR程序。对于mr节点,worker会使用`hadoop jar`方式提交任务
> Gantt图纵轴是某个流程实例下的任务实例的拓扑排序,横轴是任务实例的运行时间
<p align="center"> > 拖动工具栏中的![PNG](https://analysys.github.io/easyscheduler_docs_cn/images/toolbar_MR.png)任务节点到画板中,双击任务节点,如下图:
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/gantt.png" width="60%" />
</p>
#### 任务实例列表页 1. JAVA程序
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/task_history.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/mr_java.png" width="60%" />
</p> </p>
- 点击任务实例节点,点击 查看历史,可以查看该流程实例运行的该任务实例列表 - 主函数的class:是MR程序的入口Main Class的全路径
- 程序类型:选择JAVA语言
- 主jar包:是MR的jar包
- 命令行参数:是设置MR程序的输入参数,支持自定义参数变量的替换
- 其他参数:支持 –D、-files、-libjars、-archives格式
- 资源: 如果其他参数中引用了资源文件,需要在资源中选择指定
- 自定义参数:是MR局部的用户自定义参数,会替换脚本中以${变量}的内容
##### 查看日志 2. Python程序
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/task_log.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/mr_edit.png" width="60%" />
</p> </p>
- 点击任务实例节点,点击 查看日志,可以查看该任务实例运行的日志,如下图: - 程序类型:选择Python语言
- 主jar包:是运行MR的Python jar包
<p align="center"> - 其他参数:支持 –D、-mapper、-reducer、-input -output格式,这里可以设置用户自定义参数的输入,比如:
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/task_log2.png" width="60%" /> - -mapper "mapper.py 1" -file mapper.py -reducer reducer.py -file reducer.py –input /journey/words.txt -output /journey/out/mr/${currentTimeMillis}
</p> - 其中 -mapper 后的 mapper.py 1是两个参数,第一个参数是mapper.py,第二个参数是1
- 资源: 如果其他参数中引用了资源文件,需要在资源中选择指定
- 自定义参数:是MR局部的用户自定义参数,会替换脚本中以${变量}的内容
- 右上角是下载日志、刷新日志和放大/缩小按钮 ### Python节点
- 注意:日志查看是分片的查看,上下滚动查看 - 使用python节点,可以直接执行python脚本,对于python节点,worker会使用`python **`方式提交任务。
### 任务实例
> 任务实例是流程实例任务节点的列表 > 拖动工具栏中的![PNG](https://analysys.github.io/easyscheduler_docs_cn/images/toolbar_PYTHON.png)任务节点到画板中,双击任务节点,如下图:
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/task_list.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/python_edit.png" width="60%" />
</p> </p>
两种方式查看任务实例: - 脚本:用户开发的Python程序
- 第一种是通过流程实例任务节点 查看历史,这时查看的是此流程实例的任务实例 重跑的列表 - 资源:是指脚本中需要调用的资源文件列表
- 第二种是通过点击 流程实例 导航栏,调转到流程实例列表,这时查看的是所有流程实例的任务实例列表 - 自定义参数:是Python局部的用户自定义参数,会替换脚本中以${变量}的内容
> 查看日志:点击 查看日志 按钮,可下载和查看日志
## 系统参数
### 系统参数 ### 系统参数
<table> <table>
<tr><th>变量</th><th>含义</th></tr> <tr><th>变量</th><th>含义</th></tr>
<tr> <tr>
@ -680,7 +634,6 @@ UDF函数管理:对用户创建的UDF进行管理
- 后 N 分钟:$[HHmmss+N/24/60] - 后 N 分钟:$[HHmmss+N/24/60]
- 前 N 分钟:$[HHmmss-N/24/60] - 前 N 分钟:$[HHmmss-N/24/60]
### 用户自定义参数 ### 用户自定义参数
> 用户自定义参数分为全局参数和局部参数。全局参数是保存流程定义和流程实例的时候传递的全局参数,全局参数可以在整个流程中的任何一个任务节点的局部参数引用。 > 用户自定义参数分为全局参数和局部参数。全局参数是保存流程定义和流程实例的时候传递的全局参数,全局参数可以在整个流程中的任何一个任务节点的局部参数引用。
@ -688,13 +641,13 @@ UDF函数管理:对用户创建的UDF进行管理
> 例如: > 例如:
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/local_parameter.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/local_parameter.png" width="60%" />
</p> </p>
- global_bizdate为全局参数,引用的是系统参数。 > global_bizdate为全局参数,引用的是系统参数。
<p align="center"> <p align="center">
<img src="https://analysys.github.io/EasyScheduler/zh_CN/images/global_parameter.png" width="60%" /> <img src="https://analysys.github.io/easyscheduler_docs_cn/images/global_parameter.png" width="60%" />
</p> </p>
- 任务中local_param_bizdate通过${global_bizdate}来引用全局参数,对于脚本可以通过${local_param_bizdate}来引用变量local_param_bizdate的值,或通过JDBC直接将local_param_bizdate的值set进去 > 任务中local_param_bizdate通过${global_bizdate}来引用全局参数,对于脚本可以通过${local_param_bizdate}来引用变量local_param_bizdate的值,或通过JDBC直接将local_param_bizdate的值set进去

2
escheduler-alert/src/main/java/cn/escheduler/alert/utils/Constants.java

@ -59,6 +59,8 @@ public class Constants {
public static final String MAIL_SMTP_STARTTLS_ENABLE = "mail.smtp.starttls.enable"; public static final String MAIL_SMTP_STARTTLS_ENABLE = "mail.smtp.starttls.enable";
public static final String MAIL_SMTP_SSL_ENABLE = "mail.smtp.ssl.enable";
public static final String TEXT_HTML_CHARSET_UTF_8 = "text/html;charset=utf-8"; public static final String TEXT_HTML_CHARSET_UTF_8 = "text/html;charset=utf-8";
public static final String STRING_TRUE = "true"; public static final String STRING_TRUE = "true";

16
escheduler-alert/src/main/java/cn/escheduler/alert/utils/MailUtils.java

@ -33,6 +33,7 @@ import org.springframework.util.ResourceUtils;
import javax.mail.*; import javax.mail.*;
import javax.mail.internet.*; import javax.mail.internet.*;
import java.io.*; import java.io.*;
import java.security.Security;
import java.util.*; import java.util.*;
import static cn.escheduler.alert.utils.PropertyUtils.getInt; import static cn.escheduler.alert.utils.PropertyUtils.getInt;
@ -58,6 +59,10 @@ public class MailUtils {
public static final String xlsFilePath = getString(Constants.XLS_FILE_PATH); public static final String xlsFilePath = getString(Constants.XLS_FILE_PATH);
public static final String starttlsEnable = getString(Constants.MAIL_SMTP_STARTTLS_ENABLE);
public static final String sslEnable = getString(Constants.MAIL_SMTP_SSL_ENABLE);
private static Template MAIL_TEMPLATE; private static Template MAIL_TEMPLATE;
static { static {
@ -122,7 +127,10 @@ public class MailUtils {
//set charset //set charset
email.setCharset(Constants.UTF_8); email.setCharset(Constants.UTF_8);
// TLS verification // TLS verification
email.setTLS(true); email.setTLS(Boolean.valueOf(starttlsEnable));
// SSL verification
email.setSSL(Boolean.valueOf(sslEnable));
if (CollectionUtils.isNotEmpty(receivers)){ if (CollectionUtils.isNotEmpty(receivers)){
// receivers mail // receivers mail
for (String receiver : receivers) { for (String receiver : receivers) {
@ -269,11 +277,15 @@ public class MailUtils {
* @throws MessagingException * @throws MessagingException
*/ */
private static MimeMessage getMimeMessage(Collection<String> receivers) throws MessagingException { private static MimeMessage getMimeMessage(Collection<String> receivers) throws MessagingException {
// Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
// final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
Properties props = new Properties(); Properties props = new Properties();
props.setProperty(Constants.MAIL_HOST, mailServerHost); props.setProperty(Constants.MAIL_HOST, mailServerHost);
props.setProperty(Constants.MAIL_SMTP_AUTH, Constants.STRING_TRUE); props.setProperty(Constants.MAIL_SMTP_AUTH, Constants.STRING_TRUE);
props.setProperty(Constants.MAIL_TRANSPORT_PROTOCOL, mailProtocol); props.setProperty(Constants.MAIL_TRANSPORT_PROTOCOL, mailProtocol);
props.setProperty(Constants.MAIL_SMTP_STARTTLS_ENABLE, Constants.STRING_TRUE); props.setProperty(Constants.MAIL_SMTP_STARTTLS_ENABLE, starttlsEnable);
props.setProperty("mail.smtp.ssl.enable", sslEnable);
Authenticator auth = new Authenticator() { Authenticator auth = new Authenticator() {
@Override @Override
protected PasswordAuthentication getPasswordAuthentication() { protected PasswordAuthentication getPasswordAuthentication() {

7
escheduler-alert/src/main/resources/alert.properties

@ -8,8 +8,13 @@ mail.server.port=25
mail.sender=xxxxxxx mail.sender=xxxxxxx
mail.passwd=xxxxxxx mail.passwd=xxxxxxx
# TLS
mail.smtp.starttls.enable=false
# SSL
mail.smtp.ssl.enable=true
#xls file path,need create if not exist #xls file path,need create if not exist
xls.file.path=/opt/xls xls.file.path=/tmp/xls

39
escheduler-alert/src/main/resources/mail_templates/alert_mail_template.ftl

@ -1,38 +1 @@
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'> <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'><html><head><title> easyscheduler</title><meta name='Keywords' content=''><meta name='Description' content=''><style type="text/css">table { margin-top:0px; padding-top:0px; border:1px solid; font-size: 14px; color: #333333; border-width: 1px; border-color: #666666; border-collapse: collapse; } table th { border-width: 1px; padding: 8px; border-style: solid; border-color: #666666; background-color: #dedede; } table td { border-width: 1px; padding: 8px; border-style: solid; border-color: #666666; background-color: #ffffff; }</style></head><body style="margin:0;padding:0"><table border="1px" cellpadding="5px" cellspacing="-10px"><thead><#if title??> ${title}</#if></thead><#if content??> ${content}</#if></table></body></html>
<html>
<head><title> easyscheduler </title>
<meta name='Keywords' content=''>
<meta name='Description' content=''>
<style type="text/css">table {
font-size: 14px;
color: #333333;
border-width: 1px;
border-color: #666666;
border-collapse: collapse;
}
table th {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #dedede;
}
table td {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #ffffff;
}</style>
</head>
<body>
<table>
<thead>
<#if title??> ${title} </#if>
</thead>
<#if content??> ${content} </#if>
</table>
</body>
</html>

4
escheduler-api/pom.xml

@ -34,6 +34,10 @@
<artifactId>leveldbjni-all</artifactId> <artifactId>leveldbjni-all</artifactId>
<groupId>org.fusesource.leveldbjni</groupId> <groupId>org.fusesource.leveldbjni</groupId>
</exclusion> </exclusion>
<exclusion>
<artifactId>protobuf-java</artifactId>
<groupId>com.google.protobuf</groupId>
</exclusion>
</exclusions> </exclusions>
</dependency> </dependency>

2
escheduler-api/src/main/java/cn/escheduler/api/service/ExecutorService.java

@ -178,10 +178,12 @@ public class ExecutorService extends BaseService{
} }
ProcessDefinition processDefinition = processDao.findProcessDefineById(processInstance.getProcessDefinitionId()); ProcessDefinition processDefinition = processDao.findProcessDefineById(processInstance.getProcessDefinitionId());
if(executeType != ExecuteType.STOP && executeType != ExecuteType.PAUSE){
result = checkProcessDefinitionValid(processDefinition, processInstance.getProcessDefinitionId()); result = checkProcessDefinitionValid(processDefinition, processInstance.getProcessDefinitionId());
if (result.get(Constants.STATUS) != Status.SUCCESS) { if (result.get(Constants.STATUS) != Status.SUCCESS) {
return result; return result;
} }
}
checkResult = checkExecuteType(processInstance, executeType); checkResult = checkExecuteType(processInstance, executeType);
Status status = (Status) checkResult.get(Constants.STATUS); Status status = (Status) checkResult.get(Constants.STATUS);

8
escheduler-api/src/main/java/cn/escheduler/api/service/ProcessDefinitionService.java

@ -293,12 +293,12 @@ public class ProcessDefinitionService extends BaseDAGService {
processDefine.setTimeout(processData.getTimeout()); processDefine.setTimeout(processData.getTimeout());
//custom global params //custom global params
List<Property> globalParamsList = processData.getGlobalParams(); List<Property> globalParamsList = new ArrayList<>();
if (globalParamsList != null && globalParamsList.size() > 0) { if (processData.getGlobalParams() != null && processData.getGlobalParams().size() > 0) {
Set<Property> userDefParamsSet = new HashSet<>(globalParamsList); Set<Property> userDefParamsSet = new HashSet<>(processData.getGlobalParams());
globalParamsList = new ArrayList<>(userDefParamsSet); globalParamsList = new ArrayList<>(userDefParamsSet);
processDefine.setGlobalParamList(globalParamsList);
} }
processDefine.setGlobalParamList(globalParamsList);
processDefine.setUpdateTime(now); processDefine.setUpdateTime(now);
processDefine.setFlag(Flag.YES); processDefine.setFlag(Flag.YES);
if (processDefineMapper.update(processDefine) > 0) { if (processDefineMapper.update(processDefine) > 0) {

3
escheduler-api/src/main/java/cn/escheduler/api/service/UsersService.java

@ -115,6 +115,9 @@ public class UsersService extends BaseService {
user.setUserType(UserType.GENERAL_USER); user.setUserType(UserType.GENERAL_USER);
user.setCreateTime(now); user.setCreateTime(now);
user.setUpdateTime(now); user.setUpdateTime(now);
if (StringUtils.isEmpty(queue)){
queue = "";
}
user.setQueue(queue); user.setQueue(queue);
// save user // save user

16
escheduler-common/pom.xml

@ -148,10 +148,10 @@
<groupId>javax.servlet.jsp</groupId> <groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId> <artifactId>jsp-api</artifactId>
</exclusion> </exclusion>
<exclusion> <!--<exclusion>-->
<groupId>com.google.protobuf</groupId> <!--<groupId>com.google.protobuf</groupId>-->
<artifactId>protobuf-java</artifactId> <!--<artifactId>protobuf-java</artifactId>-->
</exclusion> <!--</exclusion>-->
</exclusions> </exclusions>
</dependency> </dependency>
@ -175,10 +175,10 @@
<groupId>org.codehaus.jackson</groupId> <groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-xc</artifactId> <artifactId>jackson-xc</artifactId>
</exclusion> </exclusion>
<exclusion> <!--<exclusion>-->
<groupId>com.google.protobuf</groupId> <!--<groupId>com.google.protobuf</groupId>-->
<artifactId>protobuf-java</artifactId> <!--<artifactId>protobuf-java</artifactId>-->
</exclusion> <!--</exclusion>-->
<exclusion> <exclusion>
<groupId>org.fusesource.leveldbjni</groupId> <groupId>org.fusesource.leveldbjni</groupId>
<artifactId>leveldbjni-all</artifactId> <artifactId>leveldbjni-all</artifactId>

5
escheduler-common/src/main/java/cn/escheduler/common/Constants.java

@ -162,6 +162,11 @@ public final class Constants {
*/ */
public static final String ZOOKEEPER_ESCHEDULER_LOCK_FAILOVER_WORKERS = "zookeeper.escheduler.lock.failover.workers"; public static final String ZOOKEEPER_ESCHEDULER_LOCK_FAILOVER_WORKERS = "zookeeper.escheduler.lock.failover.workers";
/**
* MasterServer startup failover runing and fault tolerance process
*/
public static final String ZOOKEEPER_ESCHEDULER_LOCK_FAILOVER_STARTUP_MASTERS = "zookeeper.escheduler.lock.failover.startup.masters";
/** /**
* need send warn times when master server or worker server failover * need send warn times when master server or worker server failover
*/ */

3
escheduler-common/src/main/java/cn/escheduler/common/queue/TaskQueueZkImpl.java

@ -206,7 +206,10 @@ public class TaskQueueZkImpl extends AbstractZKClient implements ITaskQueue {
String taskIdPath = tasksQueuePath + nodeValue; String taskIdPath = tasksQueuePath + nodeValue;
logger.info("consume task {}", taskIdPath); logger.info("consume task {}", taskIdPath);
try{ try{
Stat stat = zk.checkExists().forPath(taskIdPath);
if(stat != null){
zk.delete().forPath(taskIdPath); zk.delete().forPath(taskIdPath);
}
}catch(Exception e){ }catch(Exception e){
logger.error(String.format("delete task:%s from zookeeper fail, exception:" ,nodeValue) ,e); logger.error(String.format("delete task:%s from zookeeper fail, exception:" ,nodeValue) ,e);
} }

3
escheduler-common/src/main/java/cn/escheduler/common/utils/DependentUtils.java

@ -80,6 +80,9 @@ public class DependentUtils {
case "last3Hours": case "last3Hours":
result = DependentDateUtils.getLastHoursInterval(businessDate, 3); result = DependentDateUtils.getLastHoursInterval(businessDate, 3);
break; break;
case "today":
result = DependentDateUtils.getTodayInterval(businessDate);
break;
case "last1Days": case "last1Days":
result = DependentDateUtils.getLastDayInterval(businessDate, 1); result = DependentDateUtils.getLastDayInterval(businessDate, 1);
break; break;

9
escheduler-common/src/main/java/cn/escheduler/common/utils/JSONUtils.java

@ -27,10 +27,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
/** /**
* json utils * json utils
@ -109,7 +106,7 @@ public class JSONUtils {
*/ */
public static <T> List<T> toList(String json, Class<T> clazz) { public static <T> List<T> toList(String json, Class<T> clazz) {
if (StringUtils.isEmpty(json)) { if (StringUtils.isEmpty(json)) {
return null; return new ArrayList<>();
} }
try { try {
return JSONArray.parseArray(json, clazz); return JSONArray.parseArray(json, clazz);
@ -117,7 +114,7 @@ public class JSONUtils {
logger.error("JSONArray.parseArray exception!",e); logger.error("JSONArray.parseArray exception!",e);
} }
return null; return new ArrayList<>();
} }

15
escheduler-common/src/main/java/cn/escheduler/common/utils/dependent/DependentDateUtils.java

@ -42,6 +42,21 @@ public class DependentDateUtils {
return dateIntervals; return dateIntervals;
} }
/**
* get today day interval list
* @param businessDate
* @return
*/
public static List<DateInterval> getTodayInterval(Date businessDate){
List<DateInterval> dateIntervals = new ArrayList<>();
Date beginTime = DateUtils.getStartOfDay(businessDate);
Date endTime = DateUtils.getEndOfDay(businessDate);
dateIntervals.add(new DateInterval(beginTime, endTime));
return dateIntervals;
}
/** /**
* get last day interval list * get last day interval list
* @param businessDate * @param businessDate

1
escheduler-common/src/main/resources/zookeeper.properties

@ -16,6 +16,7 @@ zookeeper.escheduler.lock.workers=/escheduler/lock/workers
#escheduler failover directory #escheduler failover directory
zookeeper.escheduler.lock.failover.masters=/escheduler/lock/failover/masters zookeeper.escheduler.lock.failover.masters=/escheduler/lock/failover/masters
zookeeper.escheduler.lock.failover.workers=/escheduler/lock/failover/workers zookeeper.escheduler.lock.failover.workers=/escheduler/lock/failover/workers
zookeeper.escheduler.lock.failover.startup.masters=/escheduler/lock/failover/startup-masters
#escheduler failover directory #escheduler failover directory
zookeeper.session.timeout=300 zookeeper.session.timeout=300

11
escheduler-common/src/test/java/cn/escheduler/common/utils/DependentUtilsTest.java

@ -52,6 +52,10 @@ public class DependentUtilsTest {
public void getDateIntervalList() { public void getDateIntervalList() {
Date curDay = DateUtils.stringToDate("2019-02-05 00:00:00"); Date curDay = DateUtils.stringToDate("2019-02-05 00:00:00");
DateInterval diCur = new DateInterval(DateUtils.getStartOfDay(curDay),
DateUtils.getEndOfDay(curDay));
Date day1 = DateUtils.stringToDate("2019-02-04 00:00:00"); Date day1 = DateUtils.stringToDate("2019-02-04 00:00:00");
DateInterval di1 = new DateInterval(DateUtils.getStartOfDay(day1), DateInterval di1 = new DateInterval(DateUtils.getStartOfDay(day1),
DateUtils.getEndOfDay(day1)); DateUtils.getEndOfDay(day1));
@ -70,6 +74,13 @@ public class DependentUtilsTest {
Assert.assertEquals(dateIntervals.get(1), di1); Assert.assertEquals(dateIntervals.get(1), di1);
Assert.assertEquals(dateIntervals.get(0), di2); Assert.assertEquals(dateIntervals.get(0), di2);
dateValue = "today";
dateIntervals = DependentUtils.getDateIntervalList(curDay, dateValue);
Assert.assertEquals(dateIntervals.get(0), diCur);
} }
@Test @Test

6
escheduler-dao/pom.xml

@ -125,6 +125,12 @@
<dependency> <dependency>
<groupId>cn.analysys</groupId> <groupId>cn.analysys</groupId>
<artifactId>escheduler-common</artifactId> <artifactId>escheduler-common</artifactId>
<exclusions>
<exclusion>
<artifactId>protobuf-java</artifactId>
<groupId>com.google.protobuf</groupId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>

2
escheduler-dao/src/main/java/cn/escheduler/dao/ProcessDao.java

@ -588,10 +588,12 @@ public class ProcessDao extends AbstractBaseDao {
case START_FAILURE_TASK_PROCESS: case START_FAILURE_TASK_PROCESS:
// find failed tasks and init these tasks // find failed tasks and init these tasks
List<Integer> failedList = this.findTaskIdByInstanceState(processInstance.getId(), ExecutionStatus.FAILURE); List<Integer> failedList = this.findTaskIdByInstanceState(processInstance.getId(), ExecutionStatus.FAILURE);
List<Integer> toleranceList = this.findTaskIdByInstanceState(processInstance.getId(), ExecutionStatus.NEED_FAULT_TOLERANCE);
List<Integer> killedList = this.findTaskIdByInstanceState(processInstance.getId(), ExecutionStatus.KILL); List<Integer> killedList = this.findTaskIdByInstanceState(processInstance.getId(), ExecutionStatus.KILL);
cmdParam.remove(Constants.CMDPARAM_RECOVERY_START_NODE_STRING); cmdParam.remove(Constants.CMDPARAM_RECOVERY_START_NODE_STRING);
failedList.addAll(killedList); failedList.addAll(killedList);
failedList.addAll(toleranceList);
for(Integer taskId : failedList){ for(Integer taskId : failedList){
initTaskInstance(this.findTaskInstanceById(taskId)); initTaskInstance(this.findTaskInstanceById(taskId));
} }

5
escheduler-dao/src/main/java/cn/escheduler/dao/mapper/ProcessInstanceMapperProvider.java

@ -572,11 +572,10 @@ public class ProcessInstanceMapperProvider {
FROM(TABLE_NAME); FROM(TABLE_NAME);
WHERE("process_definition_id=#{processDefinitionId} ");
if(parameter.get("startTime") != null && parameter.get("endTime") != null if(parameter.get("startTime") != null && parameter.get("endTime") != null
){ ){
WHERE("schedule_time between #{startTime} and #{endTime} " + WHERE("process_definition_id=#{processDefinitionId} and (schedule_time between #{startTime} and #{endTime} " +
"or start_time between #{startTime} and #{endTime}"); "or start_time between #{startTime} and #{endTime})");
} }
WHERE("`state` in (" + strStates.toString() + ")"); WHERE("`state` in (" + strStates.toString() + ")");
ORDER_BY("start_time desc limit 1"); ORDER_BY("start_time desc limit 1");

7
escheduler-dao/src/main/java/cn/escheduler/dao/mapper/UserMapperProvider.java

@ -203,7 +203,9 @@ public class UserMapperProvider {
public String queryUserPaging(Map<String, Object> parameter) { public String queryUserPaging(Map<String, Object> parameter) {
return new SQL() { return new SQL() {
{ {
SELECT("u.*,t.tenant_name,q.queue_name"); SELECT("u.id,u.user_name,u.user_password,u.user_type,u.email,u.phone,u.tenant_id,u.create_time,u.update_time,t.tenant_name," +
"case when u.queue <> '' then u.queue else q.queue_name end as queue," +
"q.queue_name");
FROM(TABLE_NAME + " u "); FROM(TABLE_NAME + " u ");
LEFT_OUTER_JOIN("t_escheduler_tenant t on u.tenant_id = t.id"); LEFT_OUTER_JOIN("t_escheduler_tenant t on u.tenant_id = t.id");
LEFT_OUTER_JOIN("t_escheduler_queue q on t.queue_id = q.id"); LEFT_OUTER_JOIN("t_escheduler_queue q on t.queue_id = q.id");
@ -228,7 +230,8 @@ public class UserMapperProvider {
public String queryDetailsById(Map<String, Object> parameter) { public String queryDetailsById(Map<String, Object> parameter) {
return new SQL() { return new SQL() {
{ {
SELECT("u.*,q.queue_name,t.tenant_name"); SELECT("u.*, t.tenant_name," +
"case when u.queue <> '' then u.queue else q.queue_name end as queue_name");
FROM(TABLE_NAME + " u,t_escheduler_tenant t,t_escheduler_queue q"); FROM(TABLE_NAME + " u,t_escheduler_tenant t,t_escheduler_queue q");

4
escheduler-server/pom.xml

@ -18,6 +18,10 @@
<groupId>cn.analysys</groupId> <groupId>cn.analysys</groupId>
<artifactId>escheduler-common</artifactId> <artifactId>escheduler-common</artifactId>
<exclusions> <exclusions>
<exclusion>
<artifactId>protobuf-java</artifactId>
<groupId>com.google.protobuf</groupId>
</exclusion>
<exclusion> <exclusion>
<groupId>io.netty</groupId> <groupId>io.netty</groupId>
<artifactId>netty</artifactId> <artifactId>netty</artifactId>

34
escheduler-server/src/main/java/cn/escheduler/server/zk/ZKMasterClient.java

@ -31,6 +31,7 @@ import cn.escheduler.dao.model.TaskInstance;
import cn.escheduler.server.ResInfo; import cn.escheduler.server.ResInfo;
import cn.escheduler.server.utils.ProcessUtils; import cn.escheduler.server.utils.ProcessUtils;
import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.imps.CuratorFrameworkState;
import org.apache.curator.framework.recipes.cache.PathChildrenCache; import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener; import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
@ -111,6 +112,14 @@ public class ZKMasterClient extends AbstractZKClient {
// init dao // init dao
this.initDao(); this.initDao();
InterProcessMutex mutex = null;
try {
// create distributed lock with the root node path of the lock space as /escheduler/lock/failover/master
String znodeLock = getMasterStartUpLockPath();
mutex = new InterProcessMutex(zkClient, znodeLock);
mutex.acquire();
// init system znode // init system znode
this.initSystemZNode(); this.initSystemZNode();
@ -127,6 +136,23 @@ public class ZKMasterClient extends AbstractZKClient {
if (getActiveMasterNum() == 1) { if (getActiveMasterNum() == 1) {
processDao.selfFaultTolerant(ExecutionStatus.RUNNING_EXEUTION.ordinal(),ExecutionStatus.NEED_FAULT_TOLERANCE.ordinal()); processDao.selfFaultTolerant(ExecutionStatus.RUNNING_EXEUTION.ordinal(),ExecutionStatus.NEED_FAULT_TOLERANCE.ordinal());
} }
}catch (Exception e){
logger.error("master start up exception : " + e.getMessage(),e);
}finally {
if (mutex != null){
try {
mutex.release();
} catch (Exception e) {
if(e.getMessage().equals("instance must be started before calling this method")){
logger.warn("lock release");
}else{
logger.error("lock release failed : " + e.getMessage(),e);
}
}
}
}
} }
@ -417,6 +443,14 @@ public class ZKMasterClient extends AbstractZKClient {
return conf.getString(Constants.ZOOKEEPER_ESCHEDULER_LOCK_MASTERS); return conf.getString(Constants.ZOOKEEPER_ESCHEDULER_LOCK_MASTERS);
} }
/**
* get master start up lock path
* @return
*/
public String getMasterStartUpLockPath(){
return conf.getString(Constants.ZOOKEEPER_ESCHEDULER_LOCK_FAILOVER_STARTUP_MASTERS);
}
/** /**
* get master failover lock path * get master failover lock path
* @return * @return

4
escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/_source/commcon.js

@ -42,6 +42,10 @@ const dateValueList = {
} }
], ],
'day': [ 'day': [
{
value: 'today',
label: `${i18n.$t('today')}`
},
{ {
value: 'last1Days', value: 'last1Days',
label: `${i18n.$t('Last1Days')}` label: `${i18n.$t('Last1Days')}`

6
escheduler-ui/src/js/conf/home/pages/security/pages/users/_source/createUser.vue

@ -40,9 +40,13 @@
</template> </template>
</m-list-box-f> </m-list-box-f>
<m-list-box-f v-if="isADMIN"> <m-list-box-f v-if="isADMIN">
<template slot="name"><b>*</b>{{$t('Queue')}}</template> <template slot="name">{{$t('Queue')}}</template>
<template slot="content"> <template slot="content">
<x-select v-model="queueName"> <x-select v-model="queueName">
<x-input slot="trigger" slot-scope="{ selectedModel }" readonly :placeholder="$t('Please select a queue')" :value="selectedModel ? selectedModel.label : ''" style="width: 200px;" @on-click-icon.stop="queueName = {}">
<i slot="suffix" class="fa fa-times-circle" style="font-size: 15px;cursor: pointer;" v-show="queueName.id"></i>
<i slot="suffix" class="ans-icon-arrow-down" style="font-size: 12px;" v-show="!queueName.id"></i>
</x-input>
<x-option <x-option
v-for="city in queueList" v-for="city in queueList"
:key="city.id" :key="city.id"

1
escheduler-ui/src/js/module/i18n/locale/en_US.js

@ -390,6 +390,7 @@ export default {
'Last1Hour': 'Last1Hour', 'Last1Hour': 'Last1Hour',
'Last2Hours': 'Last2Hours', 'Last2Hours': 'Last2Hours',
'Last3Hours': 'Last3Hours', 'Last3Hours': 'Last3Hours',
'today': 'today',
'Last1Days': 'Last1Days', 'Last1Days': 'Last1Days',
'Last2Days': 'Last2Days', 'Last2Days': 'Last2Days',
'Last3Days': 'Last3Days', 'Last3Days': 'Last3Days',

4
escheduler-ui/src/js/module/i18n/locale/zh_CN.js

@ -390,6 +390,7 @@ export default {
'Last1Hour': '前1小时', 'Last1Hour': '前1小时',
'Last2Hours': '前2小时', 'Last2Hours': '前2小时',
'Last3Hours': '前3小时', 'Last3Hours': '前3小时',
'today': '今天',
'Last1Days': '昨天', 'Last1Days': '昨天',
'Last2Days': '前两天', 'Last2Days': '前两天',
'Last3Days': '前三天', 'Last3Days': '前三天',
@ -455,5 +456,6 @@ export default {
'Post Statement': '后置sql', 'Post Statement': '后置sql',
'Statement cannot be empty': '语句不能为空', 'Statement cannot be empty': '语句不能为空',
'Process Define Count': '流程定义个数', 'Process Define Count': '流程定义个数',
'Process Instance Running Count': '运行流程实例个数' 'Process Instance Running Count': '运行流程实例个数',
'Please select a queue': '请选择队列',
} }

33
install.sh

@ -45,32 +45,39 @@ mysqlDb="escheduler"
mysqlUserName="xx" mysqlUserName="xx"
# mysql 密码 # mysql 密码
# 注意:如果有特殊字符,请用 \ 转移符进行转移
mysqlPassword="xx" mysqlPassword="xx"
# conf/config/install_config.conf配置 # conf/config/install_config.conf配置
# 安装路径,不要当前路径(pwd)一样 # 注意:安装路径,不要当前路径(pwd)一样
installPath="/data1_1T/escheduler" installPath="/data1_1T/escheduler"
# 部署用户 # 部署用户
# 注意:部署用户需要有sudo权限及操作hdfs的权限,如果开启hdfs,根目录需要自行创建
deployUser="escheduler" deployUser="escheduler"
# zk集群 # zk集群
zkQuorum="192.168.xx.xx:2181,192.168.xx.xx:2181,192.168.xx.xx:2181" zkQuorum="192.168.xx.xx:2181,192.168.xx.xx:2181,192.168.xx.xx:2181"
# 安装hosts # 安装hosts
# 注意:安装调度的机器hostname列表,如果是伪分布式,则只需写一个伪分布式hostname即可
ips="ark0,ark1,ark2,ark3,ark4" ips="ark0,ark1,ark2,ark3,ark4"
# conf/config/run_config.conf配置 # conf/config/run_config.conf配置
# 运行Master的机器 # 运行Master的机器
# 注意:部署master的机器hostname列表
masters="ark0,ark1" masters="ark0,ark1"
# 运行Worker的机器 # 运行Worker的机器
# 注意:部署worker的机器hostname列表
workers="ark2,ark3,ark4" workers="ark2,ark3,ark4"
# 运行Alert的机器 # 运行Alert的机器
# 注意:部署alert server的机器hostname列表
alertServer="ark3" alertServer="ark3"
# 运行Api的机器 # 运行Api的机器
# 注意:部署api server的机器hostname列表
apiServers="ark1" apiServers="ark1"
# alert配置 # alert配置
@ -89,19 +96,27 @@ mailSender="xxxxxxxxxx"
# 发送人密码 # 发送人密码
mailPassword="xxxxxxxxxx" mailPassword="xxxxxxxxxx"
# TLS邮件协议支持
starttlsEnable="false"
# SSL邮件协议支持
# 注意:默认开启的是SSL协议,TLS和SSL只能有一个处于true状态
sslEnable="true"
# 下载Excel路径 # 下载Excel路径
xlsFilePath="/tmp/xls" xlsFilePath="/tmp/xls"
#是否启动监控自启动脚本
monitorServerState="false"
# hadoop 配置 # hadoop 配置
# 是否启动hdfs,如果启动则为true,需要配置以下hadoop相关参数; # 是否启动hdfs,如果启动则为true,需要配置以下hadoop相关参数;
# 不启动设置为false,如果为false,以下配置不需要修改 # 不启动设置为false,如果为false,以下配置不需要修改
# 特别注意:如果启动hdfs,需要自行创建hdfs根路径,也就是install.sh中的 hdfsPath
hdfsStartupSate="false" hdfsStartupSate="false"
#是否启动监控自启动脚本 # namenode地址,支持HA,需要将core-site.xml和hdfs-site.xml放到conf目录下
monitorServerState="false"
# namenode地址,支持HA,需要将core-site.xml和hdfs-site.xml放到conf目录下
namenodeFs="hdfs://mycluster:8020" namenodeFs="hdfs://mycluster:8020"
# resourcemanager HA配置,如果是单resourcemanager,这里为空即可 # resourcemanager HA配置,如果是单resourcemanager,这里为空即可
@ -157,6 +172,9 @@ mastersFailover="/escheduler/lock/failover/masters"
# zk worker容错分布式锁 # zk worker容错分布式锁
workersFailover="/escheduler/lock/failover/masters" workersFailover="/escheduler/lock/failover/masters"
# zk master启动容错分布式锁
mastersStartupFailover="/escheduler/lock/failover/startup-masters"
# zk session 超时 # zk session 超时
zkSessionTimeout="300" zkSessionTimeout="300"
@ -261,6 +279,7 @@ sed -i ${txt} "s#zookeeper.escheduler.lock.masters.*#zookeeper.escheduler.lock.m
sed -i ${txt} "s#zookeeper.escheduler.lock.workers.*#zookeeper.escheduler.lock.workers=${workersLock}#g" conf/zookeeper.properties sed -i ${txt} "s#zookeeper.escheduler.lock.workers.*#zookeeper.escheduler.lock.workers=${workersLock}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.escheduler.lock.failover.masters.*#zookeeper.escheduler.lock.failover.masters=${mastersFailover}#g" conf/zookeeper.properties sed -i ${txt} "s#zookeeper.escheduler.lock.failover.masters.*#zookeeper.escheduler.lock.failover.masters=${mastersFailover}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.escheduler.lock.failover.workers.*#zookeeper.escheduler.lock.failover.workers=${workersFailover}#g" conf/zookeeper.properties sed -i ${txt} "s#zookeeper.escheduler.lock.failover.workers.*#zookeeper.escheduler.lock.failover.workers=${workersFailover}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.escheduler.lock.failover.startup.masters.*#zookeeper.escheduler.lock.failover.startup.masters=${mastersStartupFailover}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.session.timeout.*#zookeeper.session.timeout=${zkSessionTimeout}#g" conf/zookeeper.properties sed -i ${txt} "s#zookeeper.session.timeout.*#zookeeper.session.timeout=${zkSessionTimeout}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.connection.timeout.*#zookeeper.connection.timeout=${zkConnectionTimeout}#g" conf/zookeeper.properties sed -i ${txt} "s#zookeeper.connection.timeout.*#zookeeper.connection.timeout=${zkConnectionTimeout}#g" conf/zookeeper.properties
sed -i ${txt} "s#zookeeper.retry.sleep.*#zookeeper.retry.sleep=${zkRetrySleep}#g" conf/zookeeper.properties sed -i ${txt} "s#zookeeper.retry.sleep.*#zookeeper.retry.sleep=${zkRetrySleep}#g" conf/zookeeper.properties
@ -295,6 +314,8 @@ sed -i ${txt} "s#mail.server.host.*#mail.server.host=${mailServerHost}#g" conf/a
sed -i ${txt} "s#mail.server.port.*#mail.server.port=${mailServerPort}#g" conf/alert.properties sed -i ${txt} "s#mail.server.port.*#mail.server.port=${mailServerPort}#g" conf/alert.properties
sed -i ${txt} "s#mail.sender.*#mail.sender=${mailSender}#g" conf/alert.properties sed -i ${txt} "s#mail.sender.*#mail.sender=${mailSender}#g" conf/alert.properties
sed -i ${txt} "s#mail.passwd.*#mail.passwd=${mailPassword}#g" conf/alert.properties sed -i ${txt} "s#mail.passwd.*#mail.passwd=${mailPassword}#g" conf/alert.properties
sed -i ${txt} "s#mail.smtp.starttls.enable.*#mail.smtp.starttls.enable=${starttlsEnable}#g" conf/alert.properties
sed -i ${txt} "s#mail.smtp.ssl.enable.*#mail.smtp.ssl.enable=${sslEnable}#g" conf/alert.properties
sed -i ${txt} "s#xls.file.path.*#xls.file.path=${xlsFilePath}#g" conf/alert.properties sed -i ${txt} "s#xls.file.path.*#xls.file.path=${xlsFilePath}#g" conf/alert.properties
@ -368,7 +389,7 @@ fi
echo "6,启动" echo "6,启动"
sh ${workDir}/script/start_all.sh sh ${workDir}/script/start_all.sh
# 7启动监控自启动脚本 # 7,启动监控自启动脚本
monitor_pid=${workDir}/monitor_server.pid monitor_pid=${workDir}/monitor_server.pid
if [ "true" = $monitorServerState ];then if [ "true" = $monitorServerState ];then
if [ -f $monitor_pid ]; then if [ -f $monitor_pid ]; then

2
sql/escheduler.sql

@ -426,7 +426,7 @@ CREATE TABLE `t_escheduler_worker_server` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Records of t_escheduler_user,user : admin , password : escheduler123 -- Records of t_escheduler_user,user : admin , password : escheduler123
INSERT INTO `t_escheduler_user` VALUES ('1', 'admin', '055a97b5fcd6d120372ad1976518f371', '0', '825193156@qq.com', '15001335629', '0', '2018-03-27 15:48:50', '2018-10-24 17:40:22'); INSERT INTO `t_escheduler_user` VALUES ('1', 'admin', '055a97b5fcd6d120372ad1976518f371', '0', 'xxx@qq.com', 'xxxx', '0', '2018-03-27 15:48:50', '2018-10-24 17:40:22');
INSERT INTO `t_escheduler_alertgroup` VALUES (1, 'escheduler管理员告警组', '0', 'escheduler管理员告警组','2018-11-29 10:20:39', '2018-11-29 10:20:39'); INSERT INTO `t_escheduler_alertgroup` VALUES (1, 'escheduler管理员告警组', '0', 'escheduler管理员告警组','2018-11-29 10:20:39', '2018-11-29 10:20:39');
INSERT INTO `t_escheduler_relation_user_alertgroup` VALUES ('1', '1', '1', '2018-11-29 10:22:33', '2018-11-29 10:22:33'); INSERT INTO `t_escheduler_relation_user_alertgroup` VALUES ('1', '1', '1', '2018-11-29 10:22:33', '2018-11-29 10:22:33');

Loading…
Cancel
Save