☰
azkaban-solo-server tar.gz包部署指南:单机任务调度从零到可运行
2026/9/29 5:07:06 网站建设 项目流程

简介:这是一份面向中小型团队或个人开发者的Azkaban单机版部署包,名为azkaban-solo-server-0.1.0-SNAPSHOT.tar.gz,可用于大数据工作流的可视化创建、定时调度与依赖执行。包内为已编译的服务器程序与配套脚本,用户下载解压后即可在单台机器上运行,省去源码编译环节,适合快速上手任务调度与工作流管理。文件总数暂无明细,压缩包整体约42.28MB,主要包含可执行脚本、配置文件和依赖组件,覆盖服务启动、数据库初始化与Web界面访问等基础使用需求。该资源目前已有256人学习下载,适合初学者用于本地实验环境搭建,也便于有经验的开发者快速验证Azkaban的调度机制。借助该包可体验项目分组、作业依赖编排、定时触发、执行状态与日志查看等核心功能,是了解Azkaban运行方式、进行评估选型或开展大规模调度方案前技术验证的实用素材。

1. azkaban-solo-server-0.1.0-SNAPSHOT.tar.gz:一个压缩包就能跑起的单机调度,到底靠不靠谱

假设你负责的团队只有一台服务器,却要管十几条定时任务:每天凌晨跑报表、同步订单、清理临时表。你不想一上来就搭 Hadoop 生态,也不想被 Yarn 调度折磨。azkaban-solo-server-0.1.0-SNAPSHOT.tar.gz 就是为这个场景准备的:解压、配一下端口、启动,一个能看执行日志、能编排依赖、能失败重试的调度系统就出现在浏览器里。它是 Azkaban 的单机模式,内置 H2 数据库和 Web 容器,所以文件名里的 solo-server 就是它的形态,tar.gz 则是最常见的分发方式。这个包适合自己开发自测,也适合中小团队先把调度跑起来,再决定要不要上集群。SNAPSHOT 三个字母容易吓到人,但只要你按下面这套步骤做,它一样能把活干稳。

2. 为什么选 solo-server:先弄清 Azkaban 的三种部署模式,再决定用不用这个 tar.gz

2.1 三种部署模式:solo / two-server / multi-executor 的取舍

Azkaban 官方把部署分成了三种形态,名字起得直白。solo-server 就是只有一个进程,把 Web 界面、执行引擎、数据库全部塞进同一个 JVM 里。two-server 则拆成两个独立进程,一个是 Web 服务,一个是 Executor 执行器,数据库可以换成 MySQL,这是很多生产环境的起步配置。multi-executor 是在 two-server 的基础上,部署多个 Executor 节点,让不同任务分摊到多台机器。

用一张表看区别最直接:

部署模式进程数默认数据库使用场景主要问题
solo-server1H2开发测试、小规模内部任务单点故障,并发有限
two-server2MySQL生产单机调度需要额外维护两个进程
multi-executor2+NMySQL生产集群调度需要管理多节点状态

这个 tar.gz 包属于第一种,名字里的 solo-server 已经写明白了。它最大的价值是零外部依赖:不用装 MySQL,不用配置 Redis,不需要 ZooKeeper。只要有 JDK 8,解压就能跑。但它的弱点也集中在单进程上:Web 容器崩了,执行器跟着挂;H2 数据库的连接并发一高就锁死。所以我的建议是,拿它做功能验证、跑小批量任务、当作学习工作流的工具,这些都够用。真要给核心业务做生产调度,至少换成 two-server 加 MySQL,那个稳定度完全是两个级别。

很多人会问:既然目标是省事,为什么不用现成的 Docker 镜像来安装 Azkaban?原因是官方镜像更新滞后,尤其 0.1.0-SNAPSHOT 这种开发期版本,基本不会有对应镜像。与其在网上找来历不明的镜像,不如自己把 tar.gz 包部署一遍,再按照第 6 章的方法做成自己的镜像。掌握了 tar.gz 的目录结构和配置逻辑,镜像就只是给这套东西加一层外衣,出了问题也知道去里面排查。

2.2 tar.gz 包内部长什么样:目录结构与自带的依赖

拿到 azkaban-solo-server-0.1.0-SNAPSHOT.tar.gz,别急着解压,先想想它是哪来的。0.1.0-SNAPSHOT 是开发分支的构建产物,不是官方发布版。官方发布版会有配套的 release notes 和校验值,SNAPSHOT 包通常只有构建时间。目录结构一般是这样的:

azkaban-solo-server-0.1.0-SNAPSHOT/ ├── bin/ │ ├── azkaban-solo-start.sh │ ├── azkaban-solo-shutdown.sh │ └── internal/ ├── conf/ │ ├── azkaban.properties │ ├── azkaban-users.xml │ ├── global.properties │ ├── log4j.properties │ └── plugin.properties ├── lib/ │ ├── azkaban-core-*.jar │ ├── azkaban-solo-server-*.jar │ └── 第三方依赖 jar ├── plugins/ ├── web/ │ ├── dist/ │ └── image/ └── start.sh

bin 目录负责启动和停止;conf 是整个调度的配置中心;lib 里除了 Azkaban 自己的 jar,还有 H2 驱动、Jetty 容器、Log4j 等一大批依赖。这些依赖是否齐全,决定了这个包能不能在无网环境下跑起来。SNAPSHOT 包经常出现依赖缺漏的情况,比如某个 commons-xxx.jar 没打进去,结果启动时抛 NoClassDefFoundError。遇到这种报错,不用慌,去 lib 下对比一下同版本发布包的 jar 清单,把缺的补上。这是最稳妥的做法,前提是你手边有网络环境能够拉取 Maven 依赖。

还要注意,SNAPSHOT 包和正式 release 的差异不仅体现在 jar 上。开发分支的配置模板往往不全,比如 conf 里可能没有 azkaban-users.xml,只有 users.xml 的样例。因此拿到包后的第一件事不是启动,而是先把 conf 目录里的文件列出来,和官方文档里的配置项做对照。没有的文件自己新建,不要指望启动脚本会自动生成。这个习惯能帮你省掉很多莫名其妙的错误。

2.3 前置条件:Linux x64 的 Java 8 到底该用什么方式装

Azkaban 0.1.0 系列是基于 Java 8 编译的,所以宿主机上必须有 JDK 8。这里没有商量余地,装 Java 11 甚至 Java 17 都可能在启动阶段直接失败,就算侥幸跑起来,也会在任务执行时遇到反射调用被拒的问题。我的习惯是下载 Linux x64 平台的 JDK 8 tar.gz 包,用它专属的目录安装,不污染系统自带的 java 命令。

# 假设已下载 jdk-8u202-linux-x64.tar.gz sudo mkdir -p /usr/local/java sudo tar -zxf jdk-8u202-linux-x64.tar.gz -C /usr/local/java sudo ln -s /usr/local/java/jdk1.8.0_202 /usr/local/java/jdk8 # 写进 /etc/profile 并加载 cat >> /etc/profile <<'EOF' export JAVA_HOME=/usr/local/java/jdk8 export PATH=$JAVA_HOME/bin:$PATH EOF source /etc/profile # 验证版本 java -version

参数这里说一下:tar 的 -C 指定解压目标,避免文件散落;ln -s 建一个固定路径的软链,之后升级 JDK 只要改软链指向,不用动所有脚本;把环境变量写进 /etc/profile 而不是单个用户的 ~/.bashrc,是为了让通过 service 或 cron 启动的进程也能拿到正确的 JAVA_HOME。source 之后 java -version 应该能看到 1.8 字样。如果输出的是其他版本,多半是 PATH 里有更靠前的 JDK,用 which java 查一下路径,再调整 PATH 顺序。

如果宿主机是麒麟 V10 这样的国产系统,解压 tar.gz 还要多留一个心眼。某些安全策略会让非系统目录下的可执行文件没有执行权限,解压后先用 chmod +x 把 bin 目录下的脚本加上执行权限。另外,麒麟系统默认启用 SELinux 的话,需要在解压后的目录上执行 restorecon -R,否则启动脚本可能被拦截,报错信息还是抽象的 "Permission denied"。这些和 Azkaban 本身无关,但都是我在现场排过的坑。

3. 用 tar.gz 包部署 azkaban-solo-server:从解压到看到执行流水的完整步骤

3.1 解压与目录初始化

先把包上传到服务器,我一般放在 /opt 下,方便后面做软链和系统服务。解压这一步没什么难度,但目录规划一定要做对。

# 创建统一的应用目录 sudo mkdir -p /opt/azkaban # 解压到 /opt/azkaban,得到版本号目录 sudo tar -zxf azkaban-solo-server-0.1.0-SNAPSHOT.tar.gz -C /opt/azkaban cd /opt/azkaban/azkaban-solo-server-0.1.0-SNAPSHOT/ ls -la

tar 的 -z 代表 gzip 压缩,-x 是解压,-f 指定文件名。解压后的目录名带版本号,这样同一台机器可以同时保留几套目录做版本对比。ls 执行后,先确认 bin 目录里的脚本有没有 x 权限。SNAPSHOT 包常因打包环境不同而丢失权限位,一个常见的修复命令如下:

chmod +x bin/*.sh mkdir -p logs data chown -R azkaban:azkaban /opt/azkaban

logs 目录放运行日志,data 目录放 H2 数据库文件。这个包启动脚本不会自动创建这两个目录,如果你偷懒不建,启动后它会尝试在工作目录下创建,然后你就得去解压目录里翻找。更建议的做法是单独建一个系统用户 azkaban,把整个应用目录的属主改成它,不要让 root 去跑调度任务。毕竟任务里可能包含 shell 脚本,用 root 身份执行一个不小心就是灾难。chown 那行就是把权限交给专用用户。

3.2 修改 solo-server 配置:端口、数据库、用户

所有核心配置都在 conf/azkaban.properties。这个文件是 Azkaban 的命根子,改动之前一定先备份一份带时间戳的副本。

cp conf/azkaban.properties conf/azkaban.properties.bak.$(date +%s)

然后打开 azkaban.properties,优先确认下面这几项。它们是启动的前置条件,不是优化项:

database.type=h2 h2.path=./data/h2 jetty.port=8081 azkaban.tz=Asia/Shanghai executor.host=127.0.0.1 executor.port=12321 executor.flow.threads=8

database.type 必须是 h2,因为 solo-server 自带的就是 H2 驱动,改成 mysql 反而需要额外引入连接器。h2.path 指定数据库文件落盘位置,我用相对路径 ./data/h2,好处是数据和目录绑在一起,备份直接打包目录。jetty.port 是 Web UI 的对外端口,默认 8081,如果你想改成 80,需要保证没有其他进程用 80。azkaban.tz 这个参数必须显式设成 Asia/Shanghai,否则调度时间会差 8 小时,这在后面第 4 章还会重点说。

用户认证在 conf/azkaban-users.xml。默认用户是 azkaban / azkaban,这个大家都知道,所以第一次登录后第一件事就是改密码或者加自己的用户。加管理员的方式是在 users 节点下加一行:

<user username="admin" password="admin123" roles="admin" />

注意 roles 必须写 admin,否则登录进去看不到所有项目。如果你只想给业务人员开只读账号,roles 可以写 metrics,这类账号可以看执行情况但不能执行任务。改完 XML 同样需要重启进程才会生效。

3.3 启动与停止:start 脚本的正确用法

启动前确认一下环境变量,然后执行启动脚本。这个脚本是前台运行的,所以我们要用 nohup 或直接后台挂起。

# 确认 JAVA_HOME 已生效 echo $JAVA_HOME # 启动,后台运行并记录启动日志 bin/azkaban-solo-start.sh > logs/start.out 2>&1 & # 等 10 秒再检查,Jetty 初始化和执行器注册都需要时间 sleep 10 jps -l

启动脚本内部会读取 JAVA_HOME 并拼出完整的 java 命令。solo-server 是单进程,但 jps 里可能看到两个名字,一个是 Web 容器,一个是 Executor。这是因为它们在同一个 JVM 里但用了不同的主类入口。如果你只看到一个,也正常,重点是 jps 输出里不能有带FAILED的字样。启动后立刻查看日志:

tail -n 50 logs/azkaban.log

看到 "Server running on port 8081" 或者 "Azkaban Server started" 就算成功。如果日志里有 Exception,多半是配置里的端口被占,或者 h2.path 指向的目录无写入权限。

停服时不要 kill -9。这个教训我重复过很多次,H2 数据库对异常终止没有太多自我保护机制,直接 kill 很容易留下锁文件,下一次启动直接报 Database already in use。用官方脚本关闭:

bin/azkaban-solo-shutdown.sh

关闭脚本会先通知执行器停止接受新任务,然后优雅关闭数据库。如果你实在找不到 shutdown 脚本,那就先 kill 主进程,等 5 秒再检查进程是否退出,最后再 kill 残余进程。但无论如何,正常切换版本时不要走这条粗暴路线。

3.4 访问 Web UI:第一次登录要改的默认信息

启动成功之后,打开浏览器访问http://服务器IP:8081。注意不要通过代理访问,Azkaban 对代理跳转不友好,容易登录后卡在空白页。默认用户名密码是 azkaban / azkaban。登录后先点右上角用户名,修改密码。然后我要你做的第一件事不是急着建项目,而是先确认页面上的时间和本地时间一致。如果页面上显示的时间比你的电脑慢 8 小时,回头去改 azkaban.tz。

创建一个简单项目来验证整条链路。在项目列表点击 Create Project,然后上传一个 zip 包。zip 包里的内容是一个 job 文件,比如:

# test.job type=command command=echo hello azkaban

这个文件用任意文本编辑器写好,压成 test.zip,上传。上传后点进入项目,再点击 Execute Flow,页面会跳转到执行页面,状态变成 Success 就说明 Web 到 Executor 再到 H2 数据库的全链路已经通了。如果状态一直停在 Preparing,那是 executor 端口或者 host 配置有问题,具体排查会在第 5 章讲到。

4. 必调的 5 个参数与验证清单:让 solo server 不在第二天崩掉

4.1 Java 堆内存与 GC 调优:SNAPSHOT 包默认内存的玄学

SNAPSHOT 包的启动脚本往往没有预留足够的 JVM 内存。我见过一个团队拿它跑几十个任务,第二天就 OOM,日志里全是 GC overhead limit exceeded。打开 bin 目录下的启动脚本,找到 JAVA_OPTS 那行,改成下面这样:

export JAVA_OPTS="-Xms256m -Xmx2048m -XX:MaxMetaspaceSize=512m -XX:+UseG1GC"

-Xms256m 让 JVM 启动就分配最小堆,避免运行中反复扩容。核心是 -Xmx2048m,solo-server 的 Web 端和 Executor 共用堆内存,页面响应、任务日志、Flow 状态全在这块内存里。任务一多,256 兆或 512 兆根本不够。而 -XX:MaxMetaspaceSize=512m 是因为 Azkaban 会加载大量的插件类和外部存储类,元空间容易爆。G1GC 是 JDK 8 里最成熟的垃圾回收器,比默认的 Parallel GC 在堆内存波动大时更平稳。

改完脚本后重启进程,然后观察一周内的 Full GC 频率。常见做法是在启动脚本里追加-Xloggc:logs/gc.log,这样能看到 GC 明细。如果 gc.log 里老年代频繁增长,说明任务的临时对象太多,这时候优先调低 executor.flow.threads,而不是无脑加堆内存。

有人说这是一种玄学,因为有没有效果很难速见。但我的判断方法很简单:看 JVM 是否出现连续 Full GC,以及任务在高并发时段是否偶发卡顿。只要这两个现象不出现,内存就算够用。反过来,如果每跑一次大任务就卡死,先别怀疑代码,回去检查堆参数。

4.2 时区与调度时间:为什么任务总是差 8 小时

这个坑几乎每个人都会踩一次。现象是 Web UI 上配置定时任务,明明选定的是每天 8 点,结果第二天看执行记录是凌晨 0 点。原因有两个:azkaban.tz 没设置,JVM 默认读取的是系统时区,而很多云主机默认时区是 UTC。Azkaban 的调度引擎在计算下次触发时间时,以 azkaban.tz 为准,不读 Web 端的显示时区。

所以配置要分两层做。第一层是 azkaban.properties 里显式写:

azkaban.tz=Asia/Shanghai

第二层是宿主机系统时区也要改,尤其是重启后:

sudo timedatectl set-timezone Asia/Shanghai

注意改完配置必须重启 Azkaban。这部分参数不会热加载,只改文件不重启等于白改。验证是否生效最简单的办法是:在 Web UI 建一个每 5 分钟触发一次的调度,看它的运行时间是否和本地时间一致。以前面那个例子来说,如果设置 8 点而执行时间是在上午 8 点整,说明时区对了。如果还是差 8 小时,检查系统里是否还存在其他时区干扰点,比如 JVM 启动参数里的-Duser.timezone。

4.3 数据库文件位置与备份:H2 数据的后悔药

solo-server 用 H2 存储项目、定时器、执行记录。H2 数据落在你定义的 h2.path 目录下,文件通常是 azkaban-db 或 h2 的.mv.db 格式。这个文件一旦损坏,所有工作流失效。很多人直到磁盘满了才发现这个文件占了几个 G,但部署初期就该给备份留一条退路。

备份 H2 最安全的方式是先停服再拷贝文件。不停服直接复制,很容易复制到一个处于中间状态的文件,恢复时直接报错。

bin/azkaban-solo-shutdown.sh sleep 5 cp -r data>log4j.appender.file=org.apache.log4j.RollingFileAppender log4j.appender.file.File=logs/azkaban.log log4j.appender.file.MaxFileSize=100MB log4j.appender.file.MaxBackupIndex=5

MaxFileSize 是单个文件的触发体积,达到 100MB 自动滚动,MaxBackupIndex 是保留的.1、.2这类备份文件数量。这样磁盘占用最多也就 600MB 左右,排错时还能从旧文件里找线索。如果你需要用日志做审计,可以调大到 1GB 并保留 10 个备份,但一定要警惕日志存储和 H2 数据文件都在同一个磁盘,别让日志把数据盘的余量吃光。

4.5 验证清单:用这个包之后要检查的七件事

部署完不是结束了,我每次弄完一套 solo-server 都会按下面这个表过一遍。它能把配置错误、环境问题提前暴露出来,避免第二天一早被业务方轰炸。

检查项命令或操作预期结果
Java 版本java -version输出 1.8
进程状态jps -l存在 Azkaban 相关进程
Web 端口curl -I http://localhost:8081返回 HTTP 200
执行器端口netstat -tlnp看到 12321 监听
系统时区date输出 CST
数据库文件ls -l data/h2*有近期修改的 .mv.db 文件
任务链路上传 command job 并执行状态 Success

curl 返回 200 是最直观的成功信号。如果返回 503,多半是 Web 都起来了,但 Executor 没有注册成功,这在 solo-server 里也出现过,原因是 executor.port 被占用或者 executor.host 配置指向了无法解析的地址。netstat 检查端口时,注意确认是 TCP 而不是 UDP。所有的检查项都不要只看某一项,综合通过才能判断这套系统具备交付条件。

5. 避坑:0.1.0-SNAPSHOT 包最常见的 5 个翻车现场

5.1 启动报 "Failed to start Jetty":端口被占用,但 netstat 显示没有进程

现象:执行启动脚本后,日志里出现Failed to start Jetty,lsof 查看 8081 端口却没有进程在监听。

原因:你看到的 8081 没被占用,但 Jetty 尝试绑定的时候还有另一个 TCP 端口冲突。这种情况经常发生在 Java 的临时端口区间或 IPv6 与 IPv4 绑定不一致时。还有可能是启动脚本里配置了jetty.hostname为主机名,而主机名在 /etc/hosts 里解析到了 IPv6 地址::1,Jetty 默认绑定 IPv6 失败回退不到 IPv4。

解决:在 azkaban.properties 里显式增加两行:

jetty.hostname=0.0.0.0

同时在启动脚本的 JAVA_OPTS 里追加一个参数:

export JAVA_OPTS="$JAVA_OPTS -Djava.net.preferIPv4Stack=true"

这会让 JVM 强制走 IPv4 网络栈。改完重启,问题基本消失。如果还报端口被占,换一个不常用的高位端口,比如 18081,避免和别的开发工具的默认端口抢。

5.2 明明装了 JDK 8,启动还是 UnsupportedClassVersionError

现象:在 shell 里输入 java -version 显示 1.8,但执行启动脚本时却报UnsupportedClassVersionError: org/azkaban/... Unsupported major.minor version 52.0。

原因:启动脚本里把 JAVA_HOME 写死成了另一个路径,或者系统通过 update-alternatives 把 root 用户的 java 指向了别的 JDK,而 Azkaban 进程以其他用户身份运行,读到的是不同的路径。

解决:不要依赖 PATH 传递。直接修改启动脚本,在顶部写死:

export JAVA_HOME=/usr/local/java/jdk8 export PATH=$JAVA_HOME/bin:$PATH

注意要放在脚本最前面,覆盖掉任何系统级的环境变量。然后用su - azkaban -c 'echo $JAVA_HOME'验证一下目标用户能否读到这个路径。如果你用的是 systemd 服务,还要检查 /etc/systemd/system 里的 Environment 配置。这是典型的用户环境差异导致的翻车现场,看起来像 JDK 问题,实际上是脚本里的路径黑匣子。

5.3 H2 数据库文件 "already in use":任务一跑就卡死

现象:启动没有任何问题,登录 Web UI 也正常,但一执行 Flow,任务就卡在 Ready 状态,日志出现Database may be already in use: "Locked by another process"。

原因:最常见的是上次进程被 kill -9,H2 的文件锁没有释放。另一个原因是有两个 azkaban-solo-server 进程同时指向了同一个 data 目录,比如你不小心从两个路径各启动了一次。H2 的锁不是网络锁,是进程内文件锁,一旦持有锁的进程没了,锁文件不会自动消失。

解决:先用ps -ef | grep azkaban把所有相关进程找出来,逐个 kill。然后到 data 目录下删除.lock.db和.trace.db文件。最后检查你启动时的工作目录到底在哪里,因为 h2.path 如果配成相对路径./data/h2,不同工作目录会指向不同的锁文件。更稳妥的做法是把 h2.path 改成绝对路径,比如/opt/azkaban/data/h2,这样能避免多个实例误写同一组文件。改完再启动,任务就能正常跑了。

5.4 麒麟 V10 解压 tar.gz 却提示 "No such file or directory"

现象:在麒麟 V10 服务器上解压了这个 tar.gz,进入目录执行 bin/azkaban-solo-start.sh,报错No such file or directory,但 ls 显示文件明明存在。

原因:这个报错不是文件不存在,而是脚本的 shebang 指向的/bin/bash路径不存在,或者脚本有错误的换行符。SNAPSHOT 包如果在 Windows 或编辑不当的 macOS 上打包,脚本会带上 CRLF 回车符,Linux 解释器会把/bin/bash\r当作解释路径,自然找不到。麒麟 V10 的 bash 通常还在 /bin/bash,所以更多是 CRLF 问题。

解决:用 head -1 看一下脚本第一行,然后用 dos2unix 或 sed 处理:

head -1 bin/azkaban-solo-start.sh sed -i 's/\r$//' bin/*.sh chmod +x bin/*.sh

处理后再次执行。这个方法对 tar.gz 包里所有 shell 脚本都适用,包括 internal 目录下的那些辅助脚本。国产系统上还有一种情况是安全组件拦截了非系统目录的脚本执行,这种一般修改目录挂载属性或恢复 SELinux 上下文能解决。总之,报 “No such file or directory” 时,先怀疑格式,不要怀疑文件缺失。

5.5 任务执行卡在 Preparing 状态,执行器不可达

现象:上传项目成功,点击 Execute Flow,状态长时间停在 Preparing,最后超时失败。

原因:solo-server 模式里 Web 端和 Executor 端通过 executor.port 通信。如果你在配置里写了executor.host=example.com,而该域名解析不到本机回环地址,Web 端找不到执行器。还有一种情况是服务器防火墙默认只放行了 Web 端口,没有放行 12321 这个内部通信端口。

解决:把 executor.host 设为 127.0.0.1,executor.port 设为 12321,同时防火墙放行 TCP 12321:

sudo firewall-cmd --add-port=12321/tcp --permanent sudo firewall-cmd --reload

如果你用的是云服务器,安全组规则里也要加这一条。另外,SNAPSHOT 包的执行器注册逻辑有一个已知的问题,就是启动时如果 Web 还没完全就绪,执行器可能注册失败。解决方法是启动后等 15 秒以上再访问页面,别不等日志就急着点 Execute。我在现场用过最土但有效的方法:启动脚本后加sleep 20再检测端口。

6. 把 solo-server 容器化并推送到私有仓库:从 tar.gz 到一键复用的进阶玩法

当你手头多台机器都要部署同一个 azkaban-solo-server-0.1.0-SNAPSHOT.tar.gz,一遍遍解压、改配置、验证权限太浪费时间。我更推荐把它做成镜像,用 Docker 跑起来。这样不仅环境一致,后续升级 JVM 也好控制。前提还是这个 tar.gz 包本身没问题,容器只是给包加了一层外壳。

写一个基础的 Dockerfile:

FROM openjdk:8-jre-slim COPY azkaban-solo-server-0.1.0-SNAPSHOT.tar.gz /opt/ RUN tar -zxf /opt/azkaban-solo-server-0.1.0-SNAPSHOT.tar.gz -C /opt/ && \ chmod +x /opt/azkaban-solo-server-0.1.0-SNAPSHOT/bin/*.sh && \ mkdir -p /opt/azkaban-solo-server-0.1.0-SNAPSHOT/logs \ /opt/azkaban-solo-server-0.1.0-SNAPSHOT/data WORKDIR /opt/azkaban-solo-server-0.1.0-SNAPSHOT EXPOSE 8081 12321 CMD ["bin/azkaban-solo-start.sh"]

这个 Dockerfile 有几个关键点。base 镜像选择 openjdk:8-jre-slim,镜像体积更小,而且自带 Java 8 环境,避免宿主机 JDK 版本差异。COPY 之后用 tar 命令解压到 /opt,并修复脚本权限、预创建 logs 和 data 目录。WORKDIR 切到解压目录,CMD 直接执行启动脚本。注意这里没有把端口暴露到宿主机,只是声明了容器内端口,真正运行时要加-p 8081:8081 -p 12321:12321。

构建并推送到私有仓库的命令是最常见的两步:

docker build -t registry.internal/azkaban-solo-server:0.1.0 . docker push registry.internal/azkaban-solo-server:0.1.0

如果你的 Kubernetes 集群是 KubeKey 之类的一键部署工具装出来的,那么镜像推送到私有仓库后,部署应用时只需要在 Pod 的 image 字段填上私有仓库地址,并设置imagePullPolicy: IfNotPresent,就能避免多台 Worker 各自解压 tar.gz。

这里我要讲一个自己养成的习惯:凡是 SNAPSHOT 版本,我都不直接用官方构建产物上生产。要么从源码用 Gradle 重新构建一遍再打包,要么在根目录下先生成好校验值。因为 SNAPSHOT 包没有经过严格的发布流程,运行时的问题往往在任务类型一多才暴露。但如果你只是自测,那这条路足够顺畅了。

我在几百台服务器上部署过各种版本的 Azkaban,solo-server 虽然不能扛住大规模并发,但它让我把任务编排、依赖管理、失败重试这些核心概念彻底摸透了。后来迁移到 two-server 时,几乎没花时间学习,配置差异也就集中在数据库和几个连接参数上。如果你也是第一次接触 Azkaban,我建议你先把这个 tar.gz 包跑起来,部署一次、跑两个任务、改几处配置,比看任何教程都管用。希望这些经验能帮到你,省掉我当年踩过的那一堆坑。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询