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

ElasticJobElasticJobApache定时调度ZooKeeper分布式Java2026/10/23

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,一台演示离线依赖包交付方案。已在 Ubuntu 22.04 x86_64 环境实测通过,所有命令与回显均为实测原文。

一、环境信息

实测环境拓扑(三台服务器,同一内网互通):

节点IP操作系统角色关键软件版本
zk110.89.64.10Ubuntu 24.04ZooKeeper 注册中心OpenJDK 11.0.32.1、ZooKeeper 3.8.4
app110.89.64.11Ubuntu 22.04应用构建与运行OpenJDK 17.0.20.1、Maven 3.9.9、elasticjob-lite-core 3.0.4
app210.89.64.12Ubuntu 22.04离线包交付验证OpenJDK 17.0.20.1(无 Maven)

💡 说明:ElasticJob 是 JVM 嵌入式库形态的分布式调度组件——它没有独立的服务端安装包,所谓「安装 ElasticJob」= 在业务工程中引入 elasticjob-lite-core jar 依赖 + 搭建其硬依赖的 ZooKeeper 注册中心。这与本站《BlazingMQ 介绍与选型指南》(https://www.quzuo.net/document/jEGNJizJaga8 )这类「独立服务端进程」中间件的安装方式完全不同。

实测版本选型依据(2026-10-23 实查):

组件选用版本选型依据
elasticjob-lite-core3.0.4Maven Central 最新发布版(2023-10-14);GitHub 已有 3.0.5 release 但未发布 Maven 构件,Maven 工程只能取到 3.0.4
ZooKeeper3.8.4官方要求 ZooKeeper 3.6.0+,3.8.4 为 3.8 稳定线末版(2024-02-12 构建)
OpenJDK(应用侧)17.0.20.1ElasticJob 要求 Java 8+,3.0.4 支持 JDK21 构建线,17 为生产主流
OpenJDK(ZooKeeper 侧)11.0.32.1ZooKeeper 3.8 支持 JDK 8/11/17,选 LTS 11
Maven3.9.9官方要求 Maven 3.5.0+

二、前置条件

  1. 三台服务器网络互通(应用服务器需能访问 ZooKeeper 的 2181 端口),本实测中 app1/app2 与 zk1 均在 10.89.64.0/24 内网。
  2. 各服务器具备 apt 软件源访问能力(安装 JDK 与基础工具)。
  3. 应用侧需访问 Maven 仓库(方案一);完全断网环境请直接看方案二的离线交付。
  4. 操作以 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-executor3.0.4四类内置执行器
curator-framework / curator-client / curator-recipes5.5.0ZooKeeper 客户端框架
zookeeper / zookeeper-jute(客户端)3.7.1ZK 客户端协议栈(与服务端 3.8.4 服务端兼容)
quartz2.3.2cron 表达式引擎
guava32.1.2-jre工具库
snakeyaml / gson2.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

逐项说明:

参数默认值说明
tickTime2000(ms)心跳与最小会话超时单位
initLimit10集群模式下 follower 初始连接 leader 的 tick 数(单机不生效,保留默认)
syncLimit5集群模式下 follower 与 leader 同步的最大 tick 数
dataDir(无默认)事务日志与快照目录,必须显式指定
clientPort2181客户端连接端口(ElasticJob 实例连接此端口)
maxClientCnxns60单 IP 最大并发连接数
admin.enableServertrue3.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.xmlmirrors/mirror(mirrorOf=central,url=阿里云仓库)
ZooKeeper 主配置/opt/zookeeper/conf/zoo.cfgtickTime、dataDir、clientPort、maxClientCnxns、4lw.commands.whitelist
ZooKeeper systemd 单元/etc/systemd/system/zookeeper.serviceJAVA_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 规范落点):

  1. 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)。
  2. ElasticJob 应用进程:java -Xms256m -Xmx512m ... 命令行直接控制;托管到 systemd 时写进单元文件 Environment="JAVA_OPTS=-Xms256m -Xmx512m" 并在 ExecStart 中引用 $JAVA_OPTS。生效复核:jps -v | grep JobMain(回显见 4.5,-Xms256m -Xmx512m)。
  3. 兜底复核:进程内可通过 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 进程。

十一、参考链接

  1. ElasticJob 官方站点:https://shardingsphere.apache.org/elasticjob/
  2. GitHub 仓库:https://github.com/apache/shardingsphere-elasticjob
  3. Maven Central 构件目录:https://repo1.maven.org/maven2/org/apache/shardingsphere/elasticjob/elasticjob-lite-core/
  4. ZooKeeper 3.8.4 发布页:https://archive.apache.org/dist/zookeeper/zookeeper-3.8.4/
  5. Maven 3.9.9 下载:https://archive.apache.org/dist/maven/maven-3/3.9.9/binaries/
  6. 本站选型认知篇:《ElasticJob 3.0.4 介绍与选型指南》
  7. 本站同类中间件部署参考:《Ubuntu 22.04 部署 BlazingMQ 0.95.20 指南》