ElasticJob 3.0.4 安装指南
在三台 Ubuntu 22.04 服务器上从零完成 Apache ShardingSphere ElasticJob 3.0.4 的安装与运行验证:一台搭建 ZooKeeper 3.8.4 注册中心(ElasticJob 硬依赖,systemd 托管、堆限制 256MB),一台搭建 Maven 工程在线引入 `elasticjob-lite-core` 3.0.4 并跑通单实例 SimpleJob
ElasticJob 3.0.4 安装指南
目标:在三台 Ubuntu 22.04 服务器上从零完成 Apache ShardingSphere ElasticJob 3.0.4 的安装与运行验证:一台搭建 ZooKeeper 3.8.4 注册中心(ElasticJob 硬依赖,systemd 托管、堆限制 256MB),一台搭建 Maven 工程在线引入
elasticjob-lite-core3.0.4 并跑通单实例 SimpleJob,一台演示离线依赖包交付方案。已在 Ubuntu 22.04 x86_64 环境实测通过,所有命令与回显均为实测原文。
一、环境信息
实测环境拓扑(三台服务器,同一内网互通):
| 节点 | IP | 操作系统 | 角色 | 关键软件版本 |
|---|---|---|---|---|
| zk1 | 10.89.64.10 | Ubuntu 24.04 | ZooKeeper 注册中心 | OpenJDK 11.0.32.1、ZooKeeper 3.8.4 |
| app1 | 10.89.64.11 | Ubuntu 22.04 | 应用构建与运行 | OpenJDK 17.0.20.1、Maven 3.9.9、elasticjob-lite-core 3.0.4 |
| app2 | 10.89.64.12 | Ubuntu 22.04 | 离线包交付验证 | OpenJDK 17.0.20.1(无 Maven) |
💡 说明:ElasticJob 是 JVM 嵌入式库形态的分布式调度组件——它没有独立的服务端安装包,所谓「安装 ElasticJob」= 在业务工程中引入
elasticjob-lite-corejar 依赖 + 搭建其硬依赖的 ZooKeeper 注册中心。这与本站《BlazingMQ 介绍与选型指南》(https://www.quzuo.net/document/jEGNJizJaga8 )这类「独立服务端进程」中间件的安装方式完全不同。
实测版本选型依据(2026-10-23 实查):
| 组件 | 选用版本 | 选型依据 |
|---|---|---|
| elasticjob-lite-core | 3.0.4 | Maven Central 最新发布版(2023-10-14);GitHub 已有 3.0.5 release 但未发布 Maven 构件,Maven 工程只能取到 3.0.4 |
| ZooKeeper | 3.8.4 | 官方要求 ZooKeeper 3.6.0+,3.8.4 为 3.8 稳定线末版(2024-02-12 构建) |
| OpenJDK(应用侧) | 17.0.20.1 | ElasticJob 要求 Java 8+,3.0.4 支持 JDK21 构建线,17 为生产主流 |
| OpenJDK(ZooKeeper 侧) | 11.0.32.1 | ZooKeeper 3.8 支持 JDK 8/11/17,选 LTS 11 |
| Maven | 3.9.9 | 官方要求 Maven 3.5.0+ |
二、前置条件
- 三台服务器网络互通(应用服务器需能访问 ZooKeeper 的 2181 端口),本实测中 app1/app2 与 zk1 均在 10.89.64.0/24 内网。
- 各服务器具备 apt 软件源访问能力(安装 JDK 与基础工具)。
- 应用侧需访问 Maven 仓库(方案一);完全断网环境请直接看方案二的离线交付。
- 操作以 root 执行。
以 app1 为例验证基础环境(apt 更新回显节选,实测):
apt-get update
Get:17 http://archive.ubuntu.com/ubuntu jammy-backports/universe amd64 Packages [35.6 kB]
Get:18 http://archive.ubuntu.com/ubuntu jammy-backports/main amd64 Packages [82.9 kB]
Fetched 49.0 MB in 16s (3007 kB/s)
Reading package lists...
Done
三、版本选型说明
- 为什么用 3.0.4 而不是 GitHub 上的 3.0.5:repo1.maven.org 上
org.apache.shardingsphere.elasticjob各构件目录时间戳最新为 2023-10-14(3.0.4),maven-metadata.xml 最后更新 2023-10-18;3.0.5 的 release 挂在 GitHub Releases 上(含 CVE-2025-25193、CVE-2024-47535、CVE-2024-22259 修复),但未在 Maven Central 发布构件。走 Maven 引入的工程当前只能取 3.0.4。如必须用 3.0.5,需自行 clone 源码构建(见文末参考链接)。 - 为什么选 elasticjob-lite-core 而不是单个执行器模块:lite-core 是聚合依赖,一次性引入 simple/dataflow/script/http 执行器与 ZooKeeper 注册中心实现,适合首次接入;生产中也可按需只引
elasticjob-simple-executor+elasticjob-registry-center-zookeeper-curator。 - ZooKeeper 为什么选 3.8.4:官方 README「Environment Required」明确 ZooKeeper 3.6.0+;3.8.x 是当前广泛部署的稳定线,3.8.4 为该线末版。若复用已有 ZK 集群,确认版本 ≥3.6.0 即可。
四、安装方案一(A):Maven 工程在线引入 elasticjob-lite-core(官方推荐)
本方案在 app1(10.89.64.11)执行,适合可联网的开发/生产服务器:安装 JDK → 安装 Maven → 创建工程引入依赖 → 编译。
4.1 安装 JDK 17
apt-get install -y openjdk-17-jdk-headless wget procps
输出节选(实测尾段):
Processing triggers for libc-bin (2.35-0ubuntu3.15) ...
Processing triggers for ca-certificates (20260816ubuntu0.22.04.1) ...
Updating certificates in /etc/ssl/certs...
0 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
验证:
java -version
openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 17.0.20.1+1-1-22.04-Ubuntu, mixed mode, sharing)
4.2 安装 Maven 3.9.9
下载发行包并校验 sha256(官方归档站直连缓慢时可配置 HTTP 代理,见第九章 FAQ Q6):
cd /root
wget https://archive.apache.org/dist/maven/maven-3/3.9.9/binaries/apache-maven-3.9.9-bin.tar.gz
echo "7a9cdf674fc1703d6382f5f330b3d110ea1b512b51f1652846d9e4e8a588d766 apache-maven-3.9.9-bin.tar.gz" | sha256sum -c
tar -xzf apache-maven-3.9.9-bin.tar.gz -C /opt/
ln -sfn /opt/apache-maven-3.9.9 /opt/maven
实测回显:
apache-maven-3.9.9-bin.tar.gz: OK
配置阿里云镜像加速依赖下载(/root/.m2/settings.xml):
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0">
<mirrors>
<mirror>
<id>aliyunmaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun public</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
</settings>
💡 说明:
mirrorOf为central表示仅镜像中央仓库;aliyun public聚合了中央仓库与 jcenter 内容,国内服务器下载速度通常从数十 KB/s 提升到 MB/s 级。
验证 Maven:
export PATH=/opt/maven/bin:$PATH
mvn -version
实测回显:
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: /opt/maven
Java version: 17.0.20.1, vendor: Ubuntu, runtime: /usr/lib/jvm/java-17-openjdk-amd64
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "6.8.0-138-generic", arch: "amd64", family: "unix"
4.3 创建演示工程 elasticjob-demo
创建工程目录结构 /root/elasticjob-demo/{src/main/java/com/example,src/main/resources},以下四个文件逐一写入。
文件一:/root/elasticjob-demo/pom.xml(引入 elasticjob-lite-core 3.0.4 与 logback):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>elasticjob-demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.release>11</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<elasticjob.version>3.0.4</elasticjob.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.shardingsphere.elasticjob</groupId>
<artifactId>elasticjob-lite-core</artifactId>
<version>${elasticjob.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.13</version>
</dependency>
</dependencies>
</project>
💡 技术拓展:Maven 坐标务必使用
org.apache.shardingsphere.elasticjob——3.0.0-alpha 起 groupId 从早期社区时代的com.dangdang迁移(3.0.0-alpha Release Notes 明确记录),网上旧教程中的旧坐标对应 2.x 遗留线,勿混用。
文件二:/root/elasticjob-demo/src/main/java/com/example/JavaSimpleJob.java(SimpleJob 作业实现):
package com.example;
import org.apache.shardingsphere.elasticjob.api.ShardingContext;
import org.apache.shardingsphere.elasticjob.simple.job.SimpleJob;
/**
* 演示用 SimpleJob:每次触发打印当前分片上下文。
*/
public final class JavaSimpleJob implements SimpleJob {
@Override
public void execute(final ShardingContext context) {
System.out.printf("%s [%s] trigger | shardingItem=%d shardingTotalCount=%d "
+ "shardingParameter=%s jobParameter=%s%n",
java.time.LocalDateTime.now(), Thread.currentThread().getName(),
context.getShardingItem(), context.getShardingTotalCount(),
context.getShardingParameter(), context.getJobParameter());
}
}
文件三:/root/elasticjob-demo/src/main/java/com/example/JobMain.java(注册中心 + 作业启动入口):
package com.example;
import org.apache.shardingsphere.elasticjob.api.JobConfiguration;
import org.apache.shardingsphere.elasticjob.lite.api.bootstrap.impl.ScheduleJobBootstrap;
import org.apache.shardingsphere.elasticjob.reg.base.CoordinatorRegistryCenter;
import org.apache.shardingsphere.elasticjob.reg.zookeeper.ZookeeperConfiguration;
import org.apache.shardingsphere.elasticjob.reg.zookeeper.ZookeeperRegistryCenter;
/**
* 演示工程入口:全部参数走 -D 系统属性,便于多实例与配置变更实测。
*/
public final class JobMain {
public static void main(final String[] args) {
String zk = prop("zk", "10.89.64.10:2181");
String ns = prop("ns", "elasticjob-demo");
String jobName = prop("job", "javaSimpleJob");
String cron = prop("cron", "0/5 * * * * ?");
int shards = Integer.parseInt(prop("shards", "3"));
String items = prop("items", "0=A,1=B,2=C");
boolean failover = Boolean.parseBoolean(prop("failover", "true"));
boolean misfire = Boolean.parseBoolean(prop("misfire", "true"));
boolean overwrite = Boolean.parseBoolean(prop("overwrite", "false"));
boolean monitor = Boolean.parseBoolean(prop("monitor", "true"));
String jobParam = prop("jobparam", "");
String tag = prop("tag", "instance");
CoordinatorRegistryCenter regCenter = new ZookeeperRegistryCenter(
new ZookeeperConfiguration(zk, ns));
regCenter.init();
System.out.printf("[%s] registry center init ok, zk=%s ns=%s%n", tag, zk, ns);
JobConfiguration config = JobConfiguration.newBuilder(jobName, shards)
.cron(cron)
.shardingItemParameters(items)
.jobParameter(jobParam)
.failover(failover)
.misfire(misfire)
.overwrite(overwrite)
.monitorExecution(monitor)
.build();
new ScheduleJobBootstrap(regCenter, new JavaSimpleJob(), config).schedule();
System.out.printf("[%s] job %s scheduled, cron=%s shards=%d%n", tag, jobName, cron, shards);
}
private static String prop(final String key, final String defVal) {
String v = System.getProperty(key);
return v == null || v.isEmpty() ? defVal : v;
}
}
⚠️ 排障实录:
ScheduleJobBootstrap位于org.apache.shardingsphere.elasticjob.lite.api.bootstrap.impl(注意末尾.impl)。写错包名会报(实测):[ERROR] /root/elasticjob-demo/src/main/java/com/example/JobMain.java:[4,63] cannot find symbol symbol: class ScheduleJobBootstrap location: package org.apache.shardingsphere.elasticjob.lite.api.bootstrap
文件四:/root/elasticjob-demo/src/main/resources/logback.xml(日志级别收敛为 INFO):
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
⚠️ 排障实录:logback.xml 若漏写
</root>闭合标签,应用启动时 slf4j 报(实测):Failed to auto configure default logger context Reported exception: ch.qos.logback.core.joran.spi.JoranException: Problem parsing XML document. See previously reported errors. Caused by: org.xml.sax.SAXParseException; systemId: file:/root/elasticjob-demo/target/classes/logback.xml; lineNumber: 10; columnNumber: 7; The element type "root" must be terminated by the matching end-tag "</root>".该错误不阻断进程(logback 回退默认配置打出 DEBUG 海量日志),但会让日志不可读,务必修正。
4.4 编译与依赖解析
export PATH=/opt/maven/bin:$PATH
cd /root/elasticjob-demo
mvn -B compile
首次编译自动从阿里云镜像下载依赖,输出节选(实测):
[INFO] Downloading from aliyunmaven: https://maven.aliyun.com/repository/public/org/apache/shardingsphere/elasticjob/elasticjob-lite-core/3.0.4/elasticjob-lite-core-3.0.4.pom
[INFO] Downloaded from aliyunmaven: https://maven.aliyun.com/repository/public/org/apache/shardingsphere/elasticjob/elasticjob-lite-core/3.0.4/elasticjob-lite-core-3.0.4.pom (4.9 kB at 18 kB/s)
[INFO] Downloading from aliyunmaven: https://maven.aliyun.com/repository/public/org/apache/shardingsphere/elasticjob/elasticjob-lite/3.0.4/elasticjob-lite-3.0.4.pom
[INFO] Downloaded from aliyunmaven: https://maven.aliyun.com/repository/public/org/apache/shardingsphere/elasticjob/elasticjob-lite/3.0.4/elasticjob-lite-3.0.4.pom (1.6 kB at 6.8 kB/s)
...
[INFO] --- compiler:3.13.0:compile (default-compile) @ elasticjob-demo ---
[INFO] Compiling 2 source files with javac [debug release 11] to target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.691 s
[INFO] Finished at: 2026-10-23T13:56:06Z
[INFO] ------------------------------------------------------------------------
elasticjob-lite-core 3.0.4 传递依赖的关键构件(从运行时 classpath 实测核对):
| 依赖 | 版本 | 作用 |
|---|---|---|
| elasticjob-api / infra-common / registry-center-* | 3.0.4 | 作业 API 与注册中心 SPI |
| elasticjob-simple/dataflow/script/http-executor | 3.0.4 | 四类内置执行器 |
| curator-framework / curator-client / curator-recipes | 5.5.0 | ZooKeeper 客户端框架 |
| zookeeper / zookeeper-jute(客户端) | 3.7.1 | ZK 客户端协议栈(与服务端 3.8.4 服务端兼容) |
| quartz | 2.3.2 | cron 表达式引擎 |
| guava | 32.1.2-jre | 工具库 |
| snakeyaml / gson | 2.2 / 2.10.1 | 配置与 JSON 序列化 |
4.5 启动单实例冒烟(需先完成第五章 ZooKeeper)
编译产物 + 依赖 classpath 启动(先生成 classpath 文件):
mvn -q -B dependency:build-classpath -Dmdep.outputFile=/root/cp.txt
cd /root/elasticjob-demo
nohup java -Xms256m -Xmx512m -Dtag=node-A -Dzk=10.89.64.10:2181 -Dns=elasticjob-demo \
-Djob=javaSimpleJob -Dcron="0/5 * * * * ?" -Dshards=3 -Ditems="0=A,1=B,2=C" -Doverwrite=true \
-cp target/classes:$(cat /root/cp.txt) com.example.JobMain > /root/b1_smoke.log 2>&1 &
⚠️ 排障实录:
-Dcron="0/5 * * * * ?"里的空格与*必须加双引号,否则 shell 把*展开 成当前目录文件名,实测报错:Error: Could not find or load main class pom.xml Caused by: java.lang.ClassNotFoundException: pom.xml
确认 JVM 参数已生效(jps -v,实测):
jps -v | grep JobMain
4089 JobMain -Xms256m -Xmx512m -Dtag=node-A -Dzk=10.89.64.10:2181 -Dns=elasticjob-demo -Djob=javaSimpleJob -Dcron=0/5 * * * * ? -Dshards=3 -Ditems=0=A,1=B,2=C -Doverwrite=true
观察作业触发(实测日志):
[node-A] registry center init ok, zk=10.89.64.10:2181 ns=elasticjob-demo
[node-A] job javaSimpleJob scheduled, cron=0/5 * * * * ? shards=3
2026-10-23T14:11:55.051079875 [elasticjob-javaSimpleJob-1] trigger | shardingItem=0 shardingTotalCount=3 shardingParameter=A jobParameter=
2026-10-23T14:11:55.051091371 [elasticjob-javaSimpleJob-2] trigger | shardingItem=1 shardingTotalCount=3 shardingParameter=B jobParameter=
2026-10-23T14:11:55.051096182 [elasticjob-javaSimpleJob-3] trigger | shardingItem=2 shardingTotalCount=3 shardingParameter=C jobParameter=
2026-10-23T14:12:00.017716829 [elasticjob-javaSimpleJob-4] trigger | shardingItem=0 shardingTotalCount=3 shardingParameter=A jobParameter=
单实例下 3 个分片项(0=A、1=B、2=C)全部在本实例执行,每 5 秒触发一轮,安装与运行闭环完成。
五、安装方案二(B):ZooKeeper 3.8.4 注册中心搭建(ElasticJob 硬依赖)
本方案在 zk1(10.89.64.10)执行。ElasticJob-Lite 各实例通过 ZooKeeper 协调分片与故障转移,没有 ZK 作业无法运行。
5.1 安装 JDK 11
apt-get update && apt-get install -y openjdk-11-jdk-headless wget procps net-tools curl iproute2 netcat-openbsd
输出节选(实测尾段,与 4.1 同格式):
Processing triggers for libc-bin (2.35-0ubuntu3.15) ...
Updating certificates in /etc/ssl/certs...
0 added, 0 removed; done.
done.
验证:
java -version
openjdk version "11.0.32.1" 2026-08-18
OpenJDK Runtime Environment (build 11.0.32.1+1-post-1ubuntu1-24.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 11.0.32.1+1-post-1ubuntu1-24.04-Ubuntu, mixed mode, sharing)
5.2 下载并校验 ZooKeeper 3.8.4
cd /root
wget https://archive.apache.org/dist/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
echo "284cb4675adb64794c63d95bf202d265cebddc0cda86ac86fb0ede8049de9187 apache-zookeeper-3.8.4-bin.tar.gz" | sha256sum -c
实测回显(代理加速后,完整校验通过):
apache-zookeeper-3.8.4-bin.tar.gz: OK
-rw-r--r-- 1 root root 14609453 Feb 12 2024 apache-zookeeper-3.8.4-bin.tar.gz
⚠️ 排障实录:archive.apache.org 直连速度可能低至 30-50 KB/s(实测 90 秒仅下载 24%,3450K 处
24% 32.7K 4m28s)。解决办法二选一:为 wget 配置 HTTP 代理后再下载,或在内网镜像站/有网机器下载后传到目标服务器(注意传输后必须 sha256sum 复核,本包正确值284cb467...de9187)。
5.3 解压与 zoo.cfg 基础配置
tar -xzf apache-zookeeper-3.8.4-bin.tar.gz -C /opt/
ln -sfn /opt/apache-zookeeper-3.8.4-bin /opt/zookeeper
mkdir -p /data/zookeeper /var/log/zookeeper
写入 /opt/zookeeper/conf/zoo.cfg(默认只有 zoo_sample.ncf 样例,无 zoo.cfg):
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper
clientPort=2181
maxClientCnxns=60
admin.enableServer=false
4lw.commands.whitelist=stat, srvr, mntr, ruok, conf
逐项说明:
| 参数 | 默认值 | 说明 |
|---|---|---|
| tickTime | 2000(ms) | 心跳与最小会话超时单位 |
| initLimit | 10 | 集群模式下 follower 初始连接 leader 的 tick 数(单机不生效,保留默认) |
| syncLimit | 5 | 集群模式下 follower 与 leader 同步的最大 tick 数 |
| dataDir | (无默认) | 事务日志与快照目录,必须显式指定 |
| clientPort | 2181 | 客户端连接端口(ElasticJob 实例连接此端口) |
| maxClientCnxns | 60 | 单 IP 最大并发连接数 |
| admin.enableServer | true | 3.5+ 内嵌 AdminServer(8080),与常见 Web 服务冲突,建议关闭 |
| 4lw.commands.whitelist | 仅 srvr 等 | 四字命令白名单 |
⚠️ 排障实录:3.8 默认四字白名单不含
ruok,不配置4lw.commands.whitelist时健康检查报(实测):ruok is not executed because it is not in the whitelist.加上白名单并重启后,
echo ruok | nc 127.0.0.1 2181返回imok。
5.4 systemd 托管
写 /etc/systemd/system/zookeeper.service:
[Unit]
Description=Apache ZooKeeper 3.8.4
After=network.target
[Service]
Type=forking
User=root
Environment=JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
Environment=ZOO_LOG_DIR=/var/log/zookeeper
Environment=ZK_SERVER_HEAP=256
Environment=JVMFLAGS=-Xms256m
ExecStart=/opt/zookeeper/bin/zkServer.sh start /opt/zookeeper/conf/zoo.cfg
ExecStop=/opt/zookeeper/bin/zkServer.sh stop /opt/zookeeper/conf/zoo.cfg
Restart=on-failure
[Install]
WantedBy=multi-user.target
⚠️ JVM 堆限制说明(生产必读):ZooKeeper 默认堆为
-Xmx1000m(zkEnv.sh 的ZK_SERVER_HEAP默认 1000)。注册中心是元数据服务,256MB 堆足够承载中小规模作业注册,同时避免与业务进程争内存——本实测按团队规范将堆限定在 256MB:ZK_SERVER_HEAP=256产生-Xmx256m,JVMFLAGS=-Xms256m固定初始堆。⚠️ 排障实录(systemd 环境变量引号坑):最初写作
Environment=JVMFLAGS=-Xms256m -Xmx256m(带空格未加引号),systemd 会把-Xmx256m解析成第二个(无效)赋值,导致 JVM 实际仍是默认-Xmx1000m——systemctl status zookeeper的 CGroup 行可见(实测节选):└─1490 /usr/lib/jvm/java-11-openjdk-amd64/bin/java ... -Xmx1000m -Xms256m -Dcom.sun.management.jmxremote ...规避方式:
Environment=值含空格必须加双引号(Environment="JVMFLAGS=-Xms256m -Xmx256m"),或像本方案一样拆成ZK_SERVER_HEAP=256+JVMFLAGS=-Xms256m两个无空格赋值。
启动并设置开机自启:
systemctl daemon-reload
systemctl enable --now zookeeper
实测回显:
Created symlink /etc/systemd/system/multi-user.target.wants/zookeeper.service → /etc/systemd/system/zookeeper.service.
5.5 运行状态验证
systemctl is-active zookeeper
active
systemctl status zookeeper --no-pager -l | head -12
实测回显(首启时,JVM 参数修正前):
● zookeeper.service - Apache ZooKeeper 3.8.4
Loaded: loaded (/etc/systemd/system/zookeeper.service; enabled; preset: enabled)
Active: active (running) since Fri 2026-10-23 13:51:38 UTC; 3s ago
Process: 1475 ExecStart=/opt/zookeeper/bin/zkServer.sh start /opt/zookeeper/conf/zoo.cfg (code=exited, status=0/SUCCESS)
Main PID: 1490 (java)
Tasks: 28 (limit: 629145)
Memory: 63.0M (peak: 64.7M)
CPU: 824ms
CGroup: /system.slice/zookeeper.service
└─1490 /usr/lib/jvm/java-11-openjdk-amd64/bin/java -Dzookeeper.log.dir=/var/log/zookeeper ...
端口监听:
ss -ltn | grep 2181
LISTEN 0 50 *:2181 *:*
四字命令健康检查:
echo ruok | nc 127.0.0.1 2181; echo
imok
echo srvr | nc 127.0.0.1 2181 | head -6
Zookeeper version: 3.8.4-9316c2a7a97e1666d8f4593f34dd6fc36ecc436c, built on 2024-02-12 22:16 UTC
Latency min/avg/max: 0/0.0/0
Received: 2
Sent: 1
Connections: 1
Outstanding: 0
echo mntr | nc 127.0.0.1 2181 | head -8
zk_version 3.8.4-9316c2a7a97e1666d8f4593f34dd6fc36ecc436c, built on 2024-02-12 22:16 UTC
zk_server_state standalone
zk_ephemerals_count 0
zk_num_alive_connections 1
zk_avg_latency 0.0
zk_outstanding_requests 0
zk_znode_count 5
zk_global_sessions 0
5.6 JVM 堆参数生效复核(jps -v)
修正堆配置并重启后复核:
systemctl restart zookeeper
jps -v | grep QuorumPeerMain
实测回显(JVM 参数已收敛到 256MB):
1590 QuorumPeerMain -Dzookeeper.log.dir=/var/log/zookeeper -Dzookeeper.log.file=zookeeper-root-server-zk1.log -XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError=kill -9 %p -Xmx256m -Xms256m -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false
至此 zk1 注册中心就绪(standalone 模式)。生产多节点 ZK 集群(3/5 节点 ensemble)的搭法超出本文范围,单机 standalone 已足够 ElasticJob 功能验证与中小规模生产使用。
六、安装方案三(C):离线依赖包交付(断网服务器)
适用场景:生产服务器无法访问任何 Maven 仓库。思路是先在有网的构建机(方案一完成后的 app1)打出「classes + 全量依赖 jar」的 tar 包,再拷贝到无外网的应用服务器(app2,10.89.64.12)解包运行。
6.1 构建机打包(app1)
cd /root/elasticjob-demo
mvn -q -B dependency:copy-dependencies -DoutputDirectory=target/lib
tar -C target -czf /root/elasticjob-demo-offline.tar.gz classes lib
sha256sum /root/elasticjob-demo-offline.tar.gz
实测回显:
54dccb636cda71ecc4149f6675ee4bd9f959e5a0417837c47c1484e168c3ac84 /root/elasticjob-demo-offline.tar.gz
包内 45 个依赖 jar + 编译产物 classes,总大小约 13.4MB(ls -la 实测 13394669 字节)。
6.2 目标机运行(app2)
目标机只需 JDK(无需 Maven)。按方案一 4.1 装好 JDK 17 后:
mkdir -p /opt/elasticjob-demo
tar -xzf /root/elasticjob-demo-offline.tar.gz -C /opt/elasticjob-demo
nohup java -Xms256m -Xmx512m -Dtag=offline-B -Dzk=10.89.64.10:2181 -Dns=elasticjob-demo \
-Djob=offlineSmokeJob -Dcron="0/5 * * * * ?" -Dshards=2 -Ditems="0=X,1=Y" -Doverwrite=true \
-cp "/opt/elasticjob-demo/classes:/opt/elasticjob-demo/lib/*" com.example.JobMain > /root/offline_smoke.log 2>&1 &
实测回显:
[offline-B] registry center init ok, zk=10.89.64.10:2181 ns=elasticjob-demo
[offline-B] job offlineSmokeJob scheduled, cron=0/5 * * * * ? shards=2
2026-10-23T14:12:50.040355454 [elasticjob-offlineSmokeJob-1] trigger | shardingItem=0 shardingTotalCount=2 shardingParameter=X jobParameter=
2026-10-23T14:12:50.040362566 [elasticjob-offlineSmokeJob-2] trigger | shardingItem=1 shardingTotalCount=2 shardingParameter=Y jobParameter=
2026-10-23T14:12:55.014728819 [elasticjob-offlineSmokeJob-3] trigger | shardingItem=0 shardingTotalCount=2 shardingParameter=X jobParameter=
2026-10-23T14:12:55.014920993 [elasticjob-offlineSmokeJob-4] trigger | shardingItem=1 shardingTotalCount=2 shardingParameter=Y jobParameter=
💡 注意
-cp里"classes:lib/*"的通配符必须带双引号,交给 JVM 自己展开(shell 展开会变成目录名拼接)。此外离线交付的 sha256 应随包分发,目标机解包前先复核。
七、方案对比与选择建议
| 维度 | 方案一(A)Maven 在线 | 方案二(B)ZooKeeper 搭建 | 方案三(C)离线包 |
|---|---|---|---|
| 解决的问题 | 引入 ElasticJob 依赖 | 提供硬依赖注册中心 | 断网环境交付 |
| 是否需联网 | 是(Maven 仓库) | 是(首次下载 tar.gz) | 否(目标机) |
| 升级方式 | 改 pom 版本号重新构建 | 换 tar.gz 重新解压 | 构建机重新打包分发 |
| 适用对象 | 开发/测试/可联网生产 | 所有形态(必选) | 隔离内网生产 |
| 本实测结果 | BUILD SUCCESS + 触发日志 | active + imok + jps -v 256MB | 离线触发日志正常 |
选择建议:ZooKeeper 搭建(方案二)是必选项而非可选项;能联网一律走方案一,随版本演进最省心;隔离内网用方案三,并配合内网制品库(Nexus/Artifactory)管理版本。
八、配置说明
安装涉及的配置文件位置与常用键汇总:
| 文件 | 位置 | 常用键 |
|---|---|---|
| Maven 镜像 | /root/.m2/settings.xml | mirrors/mirror(mirrorOf=central,url=阿里云仓库) |
| ZooKeeper 主配置 | /opt/zookeeper/conf/zoo.cfg | tickTime、dataDir、clientPort、maxClientCnxns、4lw.commands.whitelist |
| ZooKeeper systemd 单元 | /etc/systemd/system/zookeeper.service | JAVA_HOME、ZOO_LOG_DIR、ZK_SERVER_HEAP、JVMFLAGS、ExecStart |
| ZooKeeper 日志目录 | /var/log/zookeeper(ZOO_LOG_DIR) | zookeeper-root-server-zk1.log 等 |
| 应用 JVM 参数 | java 命令行 -Xms/-Xmx(或 systemd 单元 Environment=) | 本规范统一 256-512MB |
JVM 内存修改位置(256-512MB 规范落点):
- ZooKeeper:
/etc/systemd/system/zookeeper.service的Environment=ZK_SERVER_HEAP=256与Environment=JVMFLAGS=-Xms256m,改后systemctl daemon-reload && systemctl restart zookeeper,用jps -v | grep QuorumPeerMain复核(回显见 5.6,-Xmx256m -Xms256m)。 - ElasticJob 应用进程:
java -Xms256m -Xmx512m ...命令行直接控制;托管到 systemd 时写进单元文件Environment="JAVA_OPTS=-Xms256m -Xmx512m"并在 ExecStart 中引用$JAVA_OPTS。生效复核:jps -v | grep JobMain(回显见 4.5,-Xms256m -Xmx512m)。 - 兜底复核:进程内可通过 JMX(
os.memory.max=512MB,本实测冒烟日志中可见)或jcmd <pid> VM.flags | grep -E "MaxHeapSize|InitialHeapSize"复核实际生效堆。
作业配置(cron、分片数、分片参数等)的逐参数详解见本专栏《ElasticJob 3.0.4 配置参数详解》与《ElasticJob 3.0.4 快速上手实战》。
九、常见问题(FAQ)
Q1:GitHub 有 3.0.5,为什么 pom 里只能引到 3.0.4? Maven Central 是 Maven 工程的实际取数源。repo1.maven.org 上该 groupId 最新构件为 3.0.4(目录时间戳 2023-10-14);3.0.5 release 仅存在于 GitHub Releases。要用 3.0.5 需自行源码构建,或等待社区发布构件。CVE 敏感场景请评估 3.0.4 依赖中的已知漏洞(如 netty 4.1.76 相关 CVE-2024-47535 在 3.0.5 中通过升级依赖修复)。
Q2:mvn compile 报 cannot find symbol: class ScheduleJobBootstrap?
包名差一层 .impl:正确导入 org.apache.shardingsphere.elasticjob.lite.api.bootstrap.impl.ScheduleJobBootstrap(3.0.4 jar 内真实路径,可用 jar tf elasticjob-lite-core-3.0.4.jar | grep Bootstrap 核对)。
Q3:echo ruok | nc 127.0.0.1 2181 返回 ruok is not executed because it is not in the whitelist.?
3.8 默认四字白名单不含 ruok。在 zoo.cfg 加 4lw.commands.whitelist=stat, srvr, mntr, ruok, conf 并重启(实测前后回显见 5.3 与 5.5)。
Q4:systemd 配了 Environment=JVMFLAGS=-Xms256m -Xmx256m 但 JVM 还是 1GB 堆?
systemd 的 Environment= 值含空格必须整体加双引号,否则第二个 -Xmx256m 被当作新的(无效)赋值丢弃(实测 status 回显见 5.4 排障实录)。
Q5:wget 从 archive.apache.org 下载极慢?
直连归档站实测 30-50 KB/s。配置 HTTP 代理(export http_proxy=http://<proxy>:<port> https_proxy=... 后再 wget)或改用内网镜像;务必以 sha256 复核文件完整性(本实测:直连 90 秒 24% vs 代理后 1m37s 完整下载校验 OK)。
Q6:java -Dcron=0/5 * * * * ? 报 Could not find or load main class pom.xml?
cron 值含空格与 *,shell 展开了通配符。用双引号包裹:-Dcron="0/5 * * * * ?"。
Q7:应用启动时刷屏 Failed to auto configure default logger context?
classpath 下 logback.xml 格式错误(如漏 </root> 闭合标签,实测堆栈见 4.3 排障实录)。修正 XML 后重新编译(mvn compile 会重新拷贝 resources 到 target/classes)。
Q8:应用连不上 ZooKeeper?
依次检查:zk1 防火墙 2181 端口(ss -ltn | grep 2181);ZookeeperConfiguration 的 serverLists 与实际 IP/端口一致;namespace 命名空间是否与预期一致(ZK 上会创建同名根节点)。
十、卸载与清理
ElasticJob 应用侧(app1/app2):
pkill -f com.example.JobMain # 停止作业进程
rm -rf /root/elasticjob-demo # 删除工程(app2 为 /opt/elasticjob-demo)
rm -rf /opt/apache-maven-3.9.9 /opt/maven # app1 如需回收 Maven
rm -f /root/apache-maven-3.9.9-bin.tar.gz /root/elasticjob-demo-offline.tar.gz
apt-get purge -y openjdk-17-jdk-headless # 如需回收 JDK
ZooKeeper 侧(zk1):
systemctl disable --now zookeeper # 停止并取消开机自启
rm -f /etc/systemd/system/zookeeper.service
systemctl daemon-reload
rm -rf /opt/apache-zookeeper-3.8.4-bin /opt/zookeeper /data/zookeeper /var/log/zookeeper
rm -f /root/apache-zookeeper-3.8.4-bin.tar.gz
apt-get purge -y openjdk-11-jdk-headless # 如需回收 JDK
验证清理干净:ss -ltn | grep 2181 无输出、jps -l 无 QuorumPeerMain/JobMain 进程。
十一、参考链接
- ElasticJob 官方站点:https://shardingsphere.apache.org/elasticjob/
- GitHub 仓库:https://github.com/apache/shardingsphere-elasticjob
- Maven Central 构件目录:https://repo1.maven.org/maven2/org/apache/shardingsphere/elasticjob/elasticjob-lite-core/
- ZooKeeper 3.8.4 发布页:https://archive.apache.org/dist/zookeeper/zookeeper-3.8.4/
- Maven 3.9.9 下载:https://archive.apache.org/dist/maven/maven-3/3.9.9/binaries/
- 本站选型认知篇:《ElasticJob 3.0.4 介绍与选型指南》
- 本站同类中间件部署参考:《Ubuntu 22.04 部署 BlazingMQ 0.95.20 指南》