☰
Azkaban solo-server 0.1.0-SNAPSHOT 部署与工作流调度实战
2026/10/12 15:03:40 网站建设 项目流程

简介:本资源为Azkaban单服务器版(Solo Server)0.1.0-SNAPSHOT的已编译tar.gz包,面向需要快速搭建工作流调度环境的小型团队、个人开发者及大数据初学者。Azkaban由LinkedIn开源,用于简化Hadoop作业调度,提供Web界面创建、管理和监控工作流,支持多项目、定时任务与依赖顺序执行。Solo Server将Web服务器、执行器和内嵌H2数据库集成于同一台机器,解压后即可完成配置与启动,省去编译环节,适合本地测试与轻量级调度场景。压缩包约42.28MB,上游未提供文件总数与类型明细,但已包含运行所需的完整目录结构。目前已有256人学习下载。通过该资源,读者可快速体验项目创建、作业定义、工作流依赖编排、定时调度及日志监控等核心功能,并借助配置文件调整数据库连接、端口与日志路径,为后续迁移至集群部署打下基础。需注意SNAPSHOT版本稳定性有限,生产环境建议选用稳定版。

1. azkaban-solo-server-0.1.0-SNAPSHOT.tar.gz:一个压缩包背后藏着什么

如果你在搜索框里敲下azkaban-solo-server-0.1.0-SNAPSHOT.tar.gz,大概率不是想了解 Azkaban 的历史,而是手里已经拿到了这个包,或者正准备从源码构建它,却不确定下一步该干什么。这个文件名拆开看:azkaban是 LinkedIn 开源的批处理工作流调度器,solo-server是它三种部署模式里最轻量的一种,0.1.0-SNAPSHOT说明这是从源码主干构建出来的快照版本,不是官方发布的稳定版。合在一起,它就是一个单机可跑、自带 Web 界面和元数据库的 Azkaban 发行包。

这篇文章要解决的问题很具体:拿到这个 tar.gz 之后,怎么在本地或测试环境把它跑起来,怎么提交第一个工作流,以及为什么很多人卡在启动脚本报错、数据库连接失败、Executor 起不来这几个地方。适合谁看?适合需要快速验证 Azkaban 调度能力、不想一上来就折腾 distributed 模式多节点部署的开发和运维。单机模式虽然简单,但它的坑并不比集群模式少,只是坑的位置不一样。

2. 解压之前先搞清楚 solo-server 的目录结构和依赖

2.1 为什么 solo-server 是验证调度逻辑的最短路径

Azkaban 有三种运行模式:solo-server、two-server、distributed。solo-server 把 Web Server 和 Executor 塞进同一个 JVM 进程,元数据默认写本地 H2 数据库,不依赖 MySQL。这意味着你不需要先装数据库、不需要配多节点通信、不需要处理 Executor 和 Web Server 之间的认证。对于只想验证「我的工作流能不能按依赖跑起来」这个诉求,solo-server 是最短路径。

但短路径不等于零配置。solo-server 的 tar.gz 解压后,目录结构大致是这样的:bin/放启动和停止脚本,conf/放azkaban.properties和日志配置,lib/放所有依赖 jar,plugins/放作业类型插件,web/放 Web 资源。很多人解压完直接bin/start-solo.sh,然后发现进程秒退,原因通常出在conf/azkaban.properties里的路径没有改成绝对路径,或者 Java 版本不匹配。

我一般会先做三件事:确认 JDK 版本、检查azkaban.properties里的web.resource.dir和user.manager.xml.file路径、看一眼bin/下脚本的JAVA_OPTS有没有硬编码的内存参数。这三步做完,再启动,成功率会高很多。

2.2 解压与目录初始化的具体命令

假设你已经把azkaban-solo-server-0.1.0-SNAPSHOT.tar.gz放到了/opt/software/下,下面是我常用的解压和初始化流程:

# 创建安装目录,避免直接解压到当前目录造成文件散落 mkdir -p /opt/azkaban tar -zxvf /opt/software/azkaban-solo-server-0.1.0-SNAPSHOT.tar.gz -C /opt/azkaban # 进入解压后的目录,注意目录名可能带版本号 cd /opt/azkaban/azkaban-solo-server-0.1.0-SNAPSHOT # 查看目录结构,确认 conf 和 bin 存在 ls -lh

解压完成后,不要急着启动。先打开conf/azkaban.properties,把里面所有相对路径改成绝对路径。比如web.resource.dir=web要改成web.resource.dir=/opt/azkaban/azkaban-solo-server-0.1.0-SNAPSHOT/web,user.manager.xml.file=conf/azkaban-users.xml要改成绝对路径。这个文件里还定义了database.type=h2和h2.path,如果h2.path是相对路径,启动时会在当前工作目录下创建h2数据库文件,换一个目录启动就会找不到之前的元数据。

提示:如果你打算把这个 solo-server 当成长期测试环境用,建议把h2.path指到一个固定目录,比如/data/azkaban/h2,避免每次重启都丢历史记录。

2.3 Java 版本和内存参数怎么定

Azkaban 0.1.0-SNAPSHOT 这个分支对 JDK 8 兼容最好,JDK 11 及以上可能会遇到模块化相关的反射报错。如果你机器上有多个 JDK,可以在bin/start-solo.sh里显式指定JAVA_HOME,而不是依赖环境变量。

内存方面,solo-server 默认的JAVA_OPTS通常给得比较保守。如果你提交的工作流里有多个并行作业,建议把-Xmx调到 1G 以上。修改位置在bin/start-solo.sh里找到JAVA_OPTS那一行,追加-Xmx1024m -Xms512m。注意不要调得太大,solo-server 是单进程,Web 和 Executor 共享内存,给太多反而容易触发 Full GC 导致界面卡顿。

3. 启动 solo-server 并验证 Web 界面和 Executor 状态

3.1 启动命令与日志观察点

启动 solo-server 的命令很简单:

cd /opt/azkaban/azkaban-solo-server-0.1.0-SNAPSHOT bin/start-solo.sh

但这个脚本执行后不会把日志打到终端,而是写到logs/目录下。你需要立刻查看logs/azkaban-solo-server.log,观察几个关键点:H2 数据库是否成功初始化、Jetty 是否在 8081 端口监听、Executor 是否注册成功。如果日志里出现java.lang.ClassNotFoundException或者Address already in use,说明依赖缺失或端口冲突。

我习惯用tail -f盯着日志,同时用ss -lntp | grep 8081确认端口。如果 8081 没起来,先检查azkaban.properties里的jetty.port是不是被改过,再检查有没有其他进程占用了这个端口。

3.2 用 curl 和浏览器双重确认服务可用

日志显示启动成功后,不要只依赖浏览器。先用 curl 打一下接口:

# 检查 Web 服务是否返回 200 curl -I http://localhost:8081 # 检查登录页面是否可访问 curl -s http://localhost:8081/index | head -20

如果 curl 返回 200 但浏览器打不开,通常是防火墙或者绑定地址的问题。azkaban.properties里有个jetty.host参数,默认可能是0.0.0.0或者localhost。如果你在虚拟机里跑,想从宿主机访问,要确认绑定的是0.0.0.0而不是127.0.0.1。

浏览器打开http://localhost:8081后,默认账号密码通常是azkaban/azkaban,这个在conf/azkaban-users.xml里定义。登录进去后,重点看两个地方:Projects 页面能不能创建项目,Executor 页面能不能看到本机 Executor 处于 active 状态。如果 Executor 显示离线,但日志里没有明显报错,大概率是azkaban.properties里的executor.port和 Web Server 通信配置不一致。

3.3 提交第一个工作流:从 job 文件到 flow 执行

Azkaban 的工作流定义用.job文件,每个文件是一个作业,多个作业通过dependencies字段串联。下面是一个最小可运行示例,两个作业:prepare.job和process.job,后者依赖前者。

先创建一个项目目录:

mkdir -p /tmp/azkaban-demo cd /tmp/azkaban-demo

然后写两个 job 文件:

# prepare.job type=command command=echo "prepare data at $(date)"
# process.job type=command command=echo "process data at $(date)" dependencies=prepare

把这两个文件打成 zip 包:

zip -r demo.zip prepare.job process.job

在 Azkaban Web 界面创建项目,上传demo.zip,然后点击执行。如果一切正常,你会看到prepare先跑,成功后process才开始。如果process一直处于preparing状态,检查dependencies里写的名字是不是 job 文件名去掉.job后缀,大小写是否一致。

注意:solo-server 的 Executor 是内嵌的,作业执行日志会写到logs/目录下,但 Web 界面也能看到。如果界面一直转圈,去logs/azkaban-execserver.log里搜作业 ID,通常能看到具体报错。

4. 避坑:solo-server 启动和运行中最容易翻车的五个地方

4.1 启动脚本报 “Cannot find Java” 或版本不匹配

现象:执行bin/start-solo.sh后立刻退出,终端输出Cannot find Java或者Unsupported major.minor version。

原因:脚本依赖JAVA_HOME环境变量,或者系统默认 Java 版本不是 JDK 8。有些 Linux 发行版预装了 JRE 而不是 JDK,编译和运行都会出问题。

解决:在bin/start-solo.sh开头显式设置JAVA_HOME,比如export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64。然后用$JAVA_HOME/bin/java -version确认版本是 1.8。如果机器上只有 JDK 11,要么装 JDK 8,要么在启动参数里加--add-opens相关参数,但后者不一定能完全解决所有反射问题。

4.2 H2 数据库文件权限导致启动失败

现象:日志里出现Database may be already in use或者Permission denied,指向h2.path下的.mv.db文件。

原因:solo-server 第一次启动时会在h2.path指定目录下创建数据库文件。如果这个目录不存在,或者当前用户没有写权限,H2 就起不来。另外,如果之前启动过一次没有正常关闭,H2 会留下锁文件,再次启动会报 “already in use”。

解决:确保h2.path目录存在且当前用户可写,比如mkdir -p /data/azkaban/h2 && chmod 755 /data/azkaban/h2。如果报 already in use,先确认没有残留的 Azkaban 进程,然后删除h2.path下的.lock文件再启动。

4.3 上传 zip 包后作业一直处于 preparing 状态

现象:工作流提交后,第一个作业一直显示preparing,不进入running,也没有报错。

原因:Executor 没有正确加载作业类型插件,或者plugins/目录下的 jobtype 插件缺少依赖。solo-server 默认只带command类型,如果你用了hive、spark等类型,需要额外放插件 jar 到plugins/下。

解决:先确认azkaban.properties里azkaban.jobtype.plugin.dir指向的目录存在且包含对应插件。如果只用command类型,检查plugins/下有没有jobtype目录,里面是否有common和command相关 jar。缺少的话,从源码构建或者找对应版本的插件包补上。

4.4 端口冲突导致 Web 界面打不开

现象:启动日志显示 Jetty 启动失败,报BindException: Address already in use。

原因:8081 端口被其他进程占用,比如之前启动的 Azkaban 没关干净,或者其他 Web 服务用了这个端口。

解决:用ss -lntp | grep 8081找到占用进程,如果是残留的 Azkaban,用bin/shutdown-solo.sh关掉,或者直接kill掉。如果确实需要换端口,改azkaban.properties里的jetty.port,同时确认 Executor 通信端口executor.port没有被占用。

4.5 时区不一致导致调度时间错乱

现象:设置了定时调度的工作流,实际执行时间和预期差了几个小时。

原因:solo-server 的 JVM 时区、H2 数据库时区、以及 Web 界面显示的时区可能不一致。默认情况下,Azkaban 用 JVM 默认时区,如果服务器是 UTC 而你在东八区,调度时间就会差 8 小时。

解决:在bin/start-solo.sh的JAVA_OPTS里加-Duser.timezone=Asia/Shanghai,确保 JVM 时区正确。同时检查azkaban.properties里有没有azkaban.server.timezone相关配置,有的话一并改成Asia/Shanghai。改完重启,再提交一个定时工作流验证。

5. 进阶:把 solo-server 塞进 Docker 并做持久化

5.1 为什么 solo-server 也值得容器化

虽然 solo-server 是单机模式,但用 Docker 跑有两个实际好处:一是环境隔离,不会污染宿主机上的 Java 和数据库;二是方便迁移,把镜像和 H2 数据目录挂载出来,换一台机器直接起。热搜词里出现docker+安装azkaban,说明很多人已经在往这个方向走。但要注意,solo-server 的官方镜像不一定存在,自己写 Dockerfile 更可控。

5.2 一个可复现的 Dockerfile 和启动命令

下面这个 Dockerfile 基于openjdk:8-jre-slim,把 tar.gz 解压到镜像里,并暴露 8081 端口:

FROM openjdk:8-jre-slim # 安装必要工具,zip 用于打包工作流,curl 用于健康检查 RUN apt-get update && apt-get install -y zip curl && rm -rf /var/lib/apt/lists/* # 把 tar.gz 复制进镜像并解压 COPY azkaban-solo-server-0.1.0-SNAPSHOT.tar.gz /opt/ RUN mkdir -p /opt/azkaban && \ tar -zxvf /opt/azkaban-solo-server-0.1.0-SNAPSHOT.tar.gz -C /opt/azkaban && \ rm -f /opt/azkaban-solo-server-0.1.0-SNAPSHOT.tar.gz # 设置工作目录 WORKDIR /opt/azkaban/azkaban-solo-server-0.1.0-SNAPSHOT # 把 H2 数据目录和日志目录挂载出来,方便持久化 VOLUME ["/opt/azkaban/azkaban-solo-server-0.1.0-SNAPSHOT/h2", "/opt/azkaban/azkaban-solo-server-0.1.0-SNAPSHOT/logs"] EXPOSE 8081 # 启动 solo-server CMD ["bin/start-solo.sh"]

构建和运行命令:

# 构建镜像 docker build -t azkaban-solo:0.1.0 . # 运行容器,把 H2 数据和日志挂到宿主机 docker run -d --name azkaban-solo \ -p 8081:8081 \ -v /data/azkaban/h2:/opt/azkaban/azkaban-solo-server-0.1.0-SNAPSHOT/h2 \ -v /data/azkaban/logs:/opt/azkaban/azkaban-solo-server-0.1.0-SNAPSHOT/logs \ azkaban-solo:0.1.0

这里的关键参数是-v挂载。H2 数据库文件如果留在容器里,容器一删数据就没了。把h2目录挂出来,重建容器后历史工作流和执行记录还在。日志目录挂出来方便在宿主机上直接tail -f,不用每次都docker exec进去。

5.3 容器化之后的验证清单

容器起来后,按这个顺序验证:

检查项命令预期结果
容器状态docker ps状态为 Up,端口映射 8081
Web 服务curl -I http://localhost:8081返回 HTTP/1.1 200
登录页面curl -s http://localhost:8081/index包含登录表单
日志无异常tail -50 /data/azkaban/logs/azkaban-solo-server.log无 ClassNotFound 或 BindException
H2 文件生成ls -lh /data/azkaban/h2有.mv.db文件

如果 Web 服务返回 200 但登录后创建项目报错,去日志里搜h2关键字,通常是挂载目录权限问题。容器内进程以 root 跑的话,宿主机目录权限要放开,或者用--user指定 UID。

5.4 我踩过的一个容器时区坑

有一次在 Docker 里跑 solo-server,定时任务总是比预期晚 8 小时。查了半天,发现基础镜像openjdk:8-jre-slim默认时区是 UTC,而我在azkaban.properties里没配时区。后来在 Dockerfile 里加了一行ENV TZ=Asia/Shanghai,同时在JAVA_OPTS里加-Duser.timezone=Asia/Shanghai,问题才解决。这个坑在物理机上不一定遇到,但容器里非常常见,因为基础镜像为了通用性通常不设本地时区。

提示:如果你用 docker-compose 编排,时区配置可以写在environment里,但 JVM 参数还是要在启动脚本里改,两者缺一不可。

5.5 从 solo-server 迁移到 two-server 的时机判断

solo-server 跑通之后,什么时候该换?我的判断标准是:当你需要多个 Executor 并行跑作业,或者 Web Server 重启时不想中断正在执行的作业,就该考虑 two-server 或 distributed 了。solo-server 的 Web 和 Executor 在同一个进程里,重启 Web 必然杀掉 Executor,正在跑的作业会失败。如果你只是做功能验证和轻量调度,solo-server 完全够用,没必要为了「看起来更生产」而提前上集群。

我自己在测试环境用 solo-server 跑了半年多,每天几十个作业,H2 数据库也没出过性能问题。真正让我迁移的是有一次需要同时跑 20 个并行作业,单进程内存扛不住,才拆成了 two-server。所以别被「单机」两个字吓到,先跑起来,遇到瓶颈再换,这是最省时间的路径。希望帮到你。

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

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

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

立即咨询