【DataX】生产环境搭建DataX集群案例
【一】环境搭建
【1】服务器说明
后端:10.238.168.161
前端(含nginx):10.238.168.96
datax集群(3台):10.238.168.62、10.238.168.106、10.238.168.173
【2】用户密码管理
(1)nginx使用nginx用户
bash
# 新增nginx用户组和用户,并创建/home/nginx专属目录
groupadd nginx && useradd -g nginx nginx -d /home/nginx
# 设置nginx用户的密码,俩次输入
passwd nginx
(2)datax集群使用datax用户
bash
# 新增datax用户组和用户,并创建/home/datax专属目录
groupadd datax && useradd -g datax datax -d /home/datax
# 设置datax用户的密码,俩次输入
passwd datax
(3)前端后端使用damp用户
bash
# 新增damp用户组和用户,并创建/home/damp专属目录
groupadd damp && useradd -g damp damp -d /home/damp
# 设置damp用户的密码,俩次输入
passwd damp
(4)如果用户密码忘了
Linux 无法直接查看明文密码!
哪怕你是 root,系统里存放的永远是密码哈希(加密字符串),不保存原始明文密码。
使用root用户,可以直接重置普通用户密码(不需要知道旧密码),执行后直接输入新密码即可,不用旧密码。
bash
passwd zhangsan
【3】DataX安装启动
下载安装包
bash
mkdir /home/datax/dgs_middleware_upload
#传输"datax.zip"文件到"/home/datax/dgs_middleware_upload"
# 解压文件
cd /home/datax/dgs_middleware_upload && unzip datax.zip
# 移动文件
mv datax ../.
测试验证
bash
python /home/datax/datax/bin/datax.py /home/datax/datax/job/job.json
出现如下内容,则表明安装成功
......
2021-10-12 21:51:12.335 job-0 INFO JobContainer -
任务启动时刻 : 2021-10-12 21:51:02
任务结束时刻 : 2021-10-12 21:51:12
任务总计耗时 : 10s
任务平均流量 : 253.91KB/s
记录写入速度 : 10000rec/s
读出记录总数 : 100000
读写失败总数 : 0
【二】DataX集群搭建
【1】配置后端到nginx的ssh免密
(1)后端服务器生成生成SSH密钥对
bash
cd ~/.ssh/
ssh-keygen -t rsa
#一直回车
一路按回车键,生成客户机秘钥对

在当前后端服务器,我们可以看到在家目录自动创建一个隐藏文件夹 .ssh,并且生成两个文件,分别是私钥文件 id_rsa 和公钥文件 id_rsa.pub 。
powershell
ls /root/.ssh

(2)复制公钥到nginx服务器
使用ssh-copy-id传公钥,ssh + Tab键发现有ssh-copy-id命令
powershell
# 自动将公钥复制到目标服务器
ssh-copy-id username@serverB_IP
# 指定端口
ssh-copy-id -p 2222 username@serverB_IP
# 指定特定密钥文件
ssh-copy-id -i ~/.ssh/id_rsa_serverB username@serverB_IP
案例:
在客户机键入下面的命令,在应答的位置输入 yes,接着输入远程机的密码,之后就可以免密码登录
powershell
ssh-copy-id nginx@10.238.168.96
在远程前端服务器10.238.168.96,我们会发现,同样在用户家目录创建了一个隐藏文件夹 .ssh,这个目录下面多了一个文件 authorized_keys,这就是刚才传过来的公钥,这样下次客户机远程过来,就不用再输入密码,这种方式在集群中用得比较多。

(3)验证
执行下面命令,不需要再输入密码就代表免密成功
bash
ssh nginx@10.238.168.96
【2】配置后端到datax集群的ssh免密
(1)nginx服务器生成生成SSH密钥对
同上
(2)复制公钥到datax服务器
同上
【3】配置nginx负载均衡datax集群
bash
vim /home/nginx/nginx_home/conf/nginx.conf
# 新增以下内容
stream {
upstream datax_cluster {
server 10.238.168.62:22;
server 10.238.168.106:22;
server 10.238.168.173:22;
}
server {
listen 20144; # Nginx本机监听TCP端口20144
proxy_pass datax_cluster; # 所有访问 20144 的 TCP 连接,转发给 upstream 集群
}
}
重载 nginx:nginx -s reload
防火墙放行:Nginx 机器入站 20144,Nginx 出站访问三台 DataX 22 端口
重要前提:三台 DataX 服务器ssh 账号、密码 / 密钥完全一致
【4】后端通过nginx轮训datax集群
(1)nacos配置datax的相关信息
1-nginx的ip地址
2-nginx转发datax的监控端口20144
3-datax服务器的账号密码

- Nginx
stream{}四层代理 只转发 TCP 数据包,完全不参与 SSH 协议交互、不处理认证; - SSH 握手、账号密码校验,是Java 程序 ↔ 最终 DataX 服务器之间完成;
- Nginx 只是 "透明管道",自身不需要、也不会使用这组账号密码。
(2)后端代码
java
public static SshExecResult execCommand(String command) {
// 1. 创建SSH会话,连接配置中的主机(Nginx跳板地址:20144)
Session session = JschUtil.openSession(config.getHost(), config.getPort(), config.getUserName(), config.getPassWd(), 60 * 60 * 1000);
SshExecResult result = null;
try {
FastByteArrayOutputStream outputStream = new FastByteArrayOutputStream();
// 2. 【关键】第一条SSH命令:hostname -I | awk '{print $1}'
String ipResult = JschUtil.exec(session, "hostname -I | awk '{print $1}'", StandardCharsets.UTF_8, new FastByteArrayOutputStream());
log.info(StrUtil.format("datax服务ip:{}", ipResult));
// 3. 执行传入的业务command命令
String execResult = JschUtil.exec(session, command, StandardCharsets.UTF_8, outputStream);
// 4. 获取stderr错误输出
String errorMsg = outputStream.toString();
// 5. 封装返回对象
result = new SshExecResult();
result.setNomarlMsg(execResult);
result.setErrorMsg(errorMsg);
} catch (Exception e) {
log.error("操作异常:{}", e.getMessage(), e);
} finally {
// 6. 强制关闭ssh会话,释放连接
if (session != null) {
session.disconnect();
}
}
return result;
}
(1)建立 SSH Session
java
Session session = JschUtil.openSession(config.getHost(), config.getPort(), config.getUserName(), config.getPassWd(), 60 * 60 * 1000);
config.getHost()/getPort()= Nginx 跳板 IP + 20144 端口- 使用 JSch(Java SSH 客户端) 创建 SSH 会话,超时 1 小时
- ⚠️ 这里连接的是 Nginx 四层代理,不是直连 DataX 机器
(2)执行探测命令(核心目的)
java
String ipResult = JschUtil.exec(session, "hostname -I | awk '{print $1}'", ...);
命令含义:
bash
hostname -I # 输出本机所有内网IP(不带127.0.0.1)
awk '{print $1}' # 取第一个IP地址
为什么要执行这一条?
因为 Nginx 做了 SSH 负载均衡,程序只知道跳板地址,不知道当前这次连接落到三台 DataX 节点中的哪一台 。
通过登录进去执行 hostname,拿到真实后端 DataX 服务器内网 IP,打印日志用于追踪问题。
(3)执行业务命令
java
String execResult = JschUtil.exec(session, command, StandardCharsets.UTF_8, outputStream);
command:上层传入需要在 DataX 节点执行的 shell 指令outputStream用来捕获标准错误 stderr
【三】流程总结
bash
Java程序
↓ SSH连接 NginxIP:20144
↓ Nginx stream四层负载均衡,随机转发到 62/106/173 的22端口,不做身份校验
↓ Nginx转发TCP流 → 轮询后端DataX机器:22端口
DataX节点(被选中机器)
↓ 代码先执行 hostname -I 获取被选中的DataX本机真实IP并打印日志
↓ 再执行业务shell命令
↓ 返回输出结果
Java代码 finally关闭SSH连接