Apache Seatunnel Zeta引擎-启动脚本分析

news/2024/10/24 21:47:39/

Apache SeaTunnel Zeta引擎的集群模式启动的第一步是执行bin/seatunnel-cluster.sh脚本,所以先来学习下这个脚本。

脚本执行流程分析

脚本简要注释

#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##########
# set -e 当脚本出现异常时马上退出,后续命令不再执行
# set -u 把未定义的变量视作错误,默认情况下Bash会把未定义的变量视为空,不会报错
##########
set -eu
# resolve links - $0 may be a softlink
#$0返回当前值行的shell脚本的名称
PRG="$0"# -h 表示 如果 FILE 存在且是一个符号连接则为真
while [ -h "$PRG" ] ; do# shellcheck disable=SC2006ls=`ls -ld "$PRG"` # -d 仅列出当前目录本身# shellcheck disable=SC2006link=`expr "$ls" : '.*-> \(.*\)$'`  # 提取软连接的目标路径# 如果 link 以 / 开头,则 为true 否则为 falseif expr "$link" : '/.*' > /dev/null; thenPRG="$link"  # 以 / 开头表明 路径为全路径else# shellcheck disable=SC2006PRG=`dirname "$PRG"`/"$link"  # 不以 / 开头说明 link只是 文件名称,需要拼接全路径fi
donePRG_DIR=`dirname "$PRG"`  # 返回启动脚本的父目录bin
APP_DIR=`cd "$PRG_DIR/.." >/dev/null; pwd` # 进入启动脚本的父目录bin 的上级目录,即软件HOME目录
CONF_DIR=${APP_DIR}/config # 配置文件路径
APP_JAR=${APP_DIR}/starter/seatunnel-starter.jar  # starter jar 路径
APP_MAIN="org.apache.seatunnel.core.starter.seatunnel.SeaTunnelServer"  # starter jar main class
OUT="${APP_DIR}/logs/seatunnel-server.out" # 定义控制台日志输出文件
HELP=falseif [ -f "${CONF_DIR}/seatunnel-env.sh" ]; then  # 判断是否存在 seatunnel-env.sh# . seatunnel-env.sh 在当前进程中执行 shell脚本,从而使脚本中定义的变量函数在当前shell中生效而不是在子shell 中# 使得脚本中的环境设置对当前进程持续生效. "${CONF_DIR}/seatunnel-env.sh"  # 如果存在则加载其中的环境变量
fi# $# 参数的个数
if [ $# == 0 ]  # 判断参数的个数是否为0
thenargs=""
elseargs=$@  # $@ 脚本传入的所有参数
fiset +u  # 取消对未设置变量的使用报错
# SeaTunnel Engine Config
if [ -z $HAZELCAST_CONFIG ]; then  # -z 字符串长度为 0 则为真HAZELCAST_CONFIG=${CONF_DIR}/hazelcast.yaml  # 当不存在变量 $HAZELCAST_CONFIG 时 ,设置该变量的值
fiif [ -z $SEATUNNEL_CONFIG ]; thenSEATUNNEL_CONFIG=${CONF_DIR}/seatunnel.yaml  # 当不存在变量 $SEATUNNEL_CONFIG 时 ,设置该变量的值
fiif test ${JvmOption} ;then  # 如果变量不为空 则 test 返回trueJAVA_OPTS="${JAVA_OPTS} ${JvmOption}"
fifor i in "$@"  # 循环脚本传输的参数
doif [[ "${i}" == *"JvmOption"* ]]; then  # 如果参数包含 JvmOption 则将该变量的值赋给 JVM_OPTIONJVM_OPTION="${i}"JAVA_OPTS="${JAVA_OPTS} ${JVM_OPTION#*=}"elif [[ "${i}" == "-d" || "${i}" == "--daemon" ]]; thenDAEMON=trueelif [[ "${i}" == "-h" || "${i}" == "--help" ]]; thenHELP=truefi
doneJAVA_OPTS="${JAVA_OPTS} -Dseatunnel.config=${SEATUNNEL_CONFIG}"
JAVA_OPTS="${JAVA_OPTS} -Dhazelcast.config=${HAZELCAST_CONFIG}"# Log4j2 Config
JAVA_OPTS="${JAVA_OPTS} -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"
if [ -e "${CONF_DIR}/log4j2.properties" ]; thenJAVA_OPTS="${JAVA_OPTS} -Dlog4j2.configurationFile=${CONF_DIR}/log4j2.properties"JAVA_OPTS="${JAVA_OPTS} -Dseatunnel.logs.path=${APP_DIR}/logs"JAVA_OPTS="${JAVA_OPTS} -Dseatunnel.logs.file_name=seatunnel-engine-server"
fi# Server Debug Config
# Usage instructions:
# If you need to debug your code in cluster mode, please enable this configuration option and listen to the specified
# port in your IDE. After that, you can happily debug your code.
# JAVA_OPTS="${JAVA_OPTS} -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=5001,suspend=y"CLASS_PATH=${APP_DIR}/lib/*:${APP_JAR}  #设置CLASS_PATHwhile read line  # 用while 循环读取输入文件中的每一行
doif [[ ! $line == \#* ]] && [ -n "$line" ]; then # 如果字符串不以 # 开头,同时非空 则为真JAVA_OPTS="$JAVA_OPTS $line"fi
done < ${APP_DIR}/config/jvm_options # 将jvm_options中设置的jvm配置加入 到   JAVA_OPTSif [[ $DAEMON == true && $HELP == false ]]; then  ## 如果参数 不是help 并且 为 daemon 时 自动创建日志目录if [[ ! -d ${APP_DIR}/logs ]]; thenmkdir -p ${APP_DIR}/logsfitouch $OUT  # 创建控制台输出日志文件# 启动Java应用程序# ${JAVA_OPTS} java虚拟机的启动参数# ${CLASS_PATH} 类路径# ${APP_MAIN} Java应用程序主类# ${args}传给java应用程序的主要参数nohup java ${JAVA_OPTS} -cp ${CLASS_PATH} ${APP_MAIN} ${args} > "$OUT" 200<&- 2>&1 < /dev/null &
elsejava ${JAVA_OPTS} -cp ${CLASS_PATH} ${APP_MAIN} ${args}
fi

脚本一些特别说明

JVM相关参数

根据对脚本的分析可知,共有三处可以配置和制定JVM相关参数

执行脚本时通过命令行参数传入

可以在执行seatunnel-cluster.sh脚本时传入jvm参数,但是格式比如符合如下要求:需要格式为key=value的格式,key中必须包含字符串JvmOption,value则是具体的JVM配置项。如:

bash seatunnel-cluster.sh JvmOption="-Xms2G -Xmx2G"
bash seatunnel-cluster.sh xJvmOptionx="-Xms2G -Xmx2G"
bash seatunnel-cluster.sh -DJvmOption="-Xms2G -Xmx2G"
添加脚本

seatunnel-cluster.sh脚本第一行添加JAVA_OPTS="-Xms2G -Xmx2G"

以上两种方式官网部署文档皆有说明,如下

在配置文件jvm_options中指定

在启动脚本中有一部分代码是对 位于CONF_DIR下的jvm_options中的配置逐行加载。

虽然以上三种均会把相关配置加载到JAVA_OPTS,但是我个人更推荐通过配置文件jvm_options的方式来指定,这样既避免了对seatunnel-cluster.sh脚本进行修改,又可以以文件的形式将详细配置保存下来。

为启动脚本seatunnel-cluster.sh创建软链

根据对启动脚本的分析,允许使用 软链的方式启动seatunnel zeta服务, 可以用于在服务器中集中管理 各种服务启动脚本的场景。

用户可以通过软链固定服务启动路径,如在/usr/bin目录下指定seatunnel-cluster.sh的软链:

cd /usr/bin
ln -snf /opt/soft/seatunnel/apache-seatunnel-2.3.5/bin/seatunnel-cluster.sh seatunnel-cluster

则可通过如下命令启动服务:

/usr/bin/seatunnel-cluster

日志目录配置

根据对脚本的分析,seatunnel zeta的目录被设置为${APP_DIR}/logs, 在脚本中进行硬编码以变量seatunnel.logs.path传入JAVA_OPTS, 然后log4j2.properties通过该变量读取的日志目录的配置。

如果需要自定义目录的配置:

  1. 要么修改seatunnel-cluster.sh指定自定义的日志目录

  2. 要么修改log4j2.properties文件放弃从环境变量读取seatunnel.logs.path, 直接指定自定义的日志目录。

目前来看以上两种方式都不够友好,另外结合seatunnel-cluster.sh在执行过程中会加载seatunnel-env.sh

在对当前日志目录配置的逻辑不进行大的调整的前提下,如果把日志相关目录的配置开放到seatunnel-env.sh对于需要自定义日志目录的用户来说会更为友好,当然这需要对脚本做一定的修改。

附录

附录为脚本执行流程的文字描述,作为对执行流程图无法表达的内容的补充:

脚本大意如下

首先获取当前执行脚本的名称,然后判断执行为脚本文件是否属于软链接,如果是软连接则获取软连接指向的原始脚本文件,并获取seatunnel-cluster.sh所在目录bin,根据获取到的bin目录获取SeatunnelHOME目录并赋值为APP_DIR,同时设置 配置文件目录 为CONFIG_DIR,并且定义seatunnel-starter.jar的路径为APP_JAR

设置org.apache.seatunnel.core.starter.seatunnel.SeaTunnelServer为 main classAPP_MAIN,定义控制台日志输出文件 为OUT

判断是否存在seatunnel-env.sh, 如果存在则执行该脚本将环境变量加载到当前进程。

判断传入的参数个数,如果为0,则将参数置为"", 否则将所有参数赋给arg

判断HAZELCAST_CONFIG变量是否存在,不存在则将hazelcast.yaml文件路径赋值给它。

判断SEATUNNEL_CONFIG变量是否存在,不存在则将seatunnel.yaml文件路径赋值给它。

判断JvmOption变量是否存在,若存在就添加到JAVA_OPTS参数当中。

循环判断脚本传入的所有参数

若参数包含字符串JvmOption, 则认定该参数为 JVM配置,并且从该参数开头删除第一个==之前的字符,将剩下的内容添加到参数JAVA_OPTS当中。

这一点说明,可以在启动脚本时传递 JVM参数,但是对格式有一定要求,即 需要格式为 key=value的格式,key中必须包含字符串JvmOption,value 则是具体的JVM配置项。

若参数为-d--daemon, 则将变量DAEMON设置为 true。

若参数为-h--help, 则将变量HELP设置为true。

HAZELCAST_CONFIGSEATUNNEL_CONFIG变量添加到 参数JAVA_OPTS

将日志配置-Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector添加到参数JAVA_OPTS

判断log4j2.properties日志配置文件是否存在,若存在则将-Dlog4j2.configurationFile=${CONF_DIR}/log4j2.properties-Dseatunnel.logs.path=${APP_DIR}/logs-Dseatunnel.logs.file_name=seatunnel-engine-server添加到参数JAVA_OPTS

设置CLASS_PATH,然后将jvm_options配置文件中的配置逐行加入到 参数JAVA_OPTS

  • 如果变量DEAMONtrue并且 变量HELPfalse
 1. 判断日志目录 ` ${APP_DIR}/logs`是否存在,不存在则创建2. 创建控制台日志输出文件3. 运行命令 `nohup java ${JAVA_OPTS} -cp ${CLASS_PATH} ${APP_MAIN} ${args} > "$OUT" 200<&- 2>&1 < /dev/null &`后台启动 `Seatunnel ` Zeta 引擎
  • 如果变量DEAMONtrue并且 变量HELPtrue:
  1. 运行命令`java ${JAVA_OPTS} -cp ${CLASS_PATH} ${APP_MAIN} ${args}`前台运行 `Seatunnel Zeta引擎`
  • 如果变量DEAMONfalse:
  1. 运行命令`java ${JAVA_OPTS} -cp ${CLASS_PATH} ${APP_MAIN} ${args}`前台运行 `Seatunnel Zeta引擎`

到此为止,已经完成整个脚本的执行,成功启动SeaTunnel Zeta引擎。以上为作者个人学习解读,如果错误之处,欢迎批评指正!!!

本文由 白鲸开源科技 提供发布支持!


http://www.ppmy.cn/news/1541672.html

相关文章

关于MyBatis的一些面试题

mybatis的执行流程 MyBatis 的执行流程主要包括 SQL 解析、参数绑定、执行查询/更新、结果映射等几个步骤。下面详细解释每个步骤的执行流程&#xff1a; 1. 加载配置文件和映射文件 加载 MyBatis 配置文件&#xff1a;启动时&#xff0c;MyBatis 通过 SqlSessionFactoryBui…

十五、【智能体】消息节点:流式与非流式输出的比较分析

想象一个我们使用电脑场景&#xff1a;当我们在copy一个很大的文件&#xff0c;电脑会显示“正在复制”&#xff0c;然后还有一个进度条。 在智能体中&#xff0c;消息节点的作用是告知用户当前任务执行到什么阶段了&#xff0c;起一个提示作用。 在扣子中&#xff0c;消息的输…

CSS学习(Grid布局和flex布局比较)

grid网格布局真香&#xff0c;比flex方便太多了&#xff0c;grid-template-columns用法 文章目录 flex布局的时候网格grid布局的时候可以修改某一列的像素可以修改某一列的宽度占比自适应屏幕分列让第一个元素长宽都占2个 flex布局的时候 最后一行不够4个的时候 最下面一行无法…

图书库存控制:Spring Boot进销存系统的应用

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

android黑屏问题记录

近期出现了一个黑屏问题&#xff1a; 仪表显示&#xff0c;主副屏黑的 &#xff1a;原因背光开启太晚&#xff0c;导致拍照时候是黑的&#xff0c;太晚的原因是绘制进程出现异常导致重启延后了时间&#xff0c;绘制进程crash原因是hwc调用底层库卡住&#xff0c;需更新hwc对应的…

Java处理大数据小技巧:深入探讨与实践

引言 一、选择合适的数据结构 1. 使用高效的集合 2. 并发安全的数据结构 二、内存管理 1. JVM参数调优 2. 避免内存泄漏 三、并行计算与分布式处理 1. 利用Java并发API 2. 分布式框架 四、数据压缩与序列化 1. 数据压缩 2. 高效序列化 五、外部存储与缓存 1. NoS…

基于Java微信小程序的高校教务管理系统的详细设计和实现(源码+lw+部署文档+讲解等)

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不…

JavaScript初级课程 variables

下载node。 1. 申明变量 variables.js let message "Hello!"; message "World"; console.log(message);node variables.js2. 申明不会变的变量 const COLOR_GREEN "green"; console.log(COLOR_GREEN)3. 数据类型 Data Types [number, B…