当前位置: 首页 > news >正文

Kettle Carte 服务实战:从作业提交到日志监控全流程自动化(附 Shell 脚本)

在数据仓库建设和 ETL 开发中,Kettle(Pentaho Data Integration)是常用工具,而 Carte 服务作为 Kettle 的远程执行引擎,能够实现作业的分布式调度与监控。本文将从实际问题出发,详细讲解如何通过 Shell 脚本实现 Kettle 作业提交、状态查询与日志监控的全自动化,解决 Carte 服务调用中的常见痛点(如日志获取失败、图形界面卡顿等)。

一、背景与痛点

在ETL开发过程中,调试是一个麻烦的事情,在windows系统上进行调试,数据量和网络问题,导致执行很慢。后将其使用git拉取到服务器执行,有点麻烦的是需要多个提交代码的步骤。
原先是再服务器上使用的kitchen.sh,每次启动都得重复启动kettle,极大的影响了调试的速度,有时候就改一点点东西,也要在那等它启动,作为资深的打工人,我是决定不允许的,后改 Kettle Carte 服务进行调用,直接省掉了启动kettle的过程,极大的提高了我打工的效率。
在使用 Kettle Carte 服务时,我们常遇到以下问题:
日志获取困难:
直接通过作业 ID 查询日志时易出现 404,需同时指定作业名称与 ID 才能正常获取;这个费了我老大的劲了,之前一直以为给Job的id就行了,没想到也得给Job的名称,两个都给才行,这反直觉的设计,好难受。问了AI也是这样说的,就很坑。
手动操作繁琐:
每次提交作业后需手动查询状态,无法实时跟踪执行进度;
稳定性不足:
Git 代码拉取失败、Carte 服务认证错误等问题缺乏容错机制。
针对以上痛点,本文提供一套 Shell 脚本解决方案,实现从代码拉取到日志监控的端到端自动化。

二、核心原理:Carte 服务接口解析

Carte 服务提供了一系列 HTTP 接口,用于作业 / 转换的提交与监控,核心接口如下:
接口功能 接口 URL 格式 关键参数说明
提交作业 http://{host}:{port}/kettle/executeJob/ job:作业文件路径;param:{key}:作业参数;-u:Carte 认证用户名密码
查询作业状态与日志 http://{host}:{port}/kettle/jobStatus/ name:作业名称;id:作业 ID;from:日志起始行数(避免重复打印)
获取所有作业状态(XML) http://{host}:{port}/kettle/status?xml=Y 批量获取当前运行的作业 ID、名称、状态,用于自动解析作业信息
关键注意点:
单独使用jobid参数查询日志时可能返回 404,需同时携带name(作业名称)和id(作业 ID)才能正确获取日志,这是解决日志获取失败的核心技巧。

三、全自动化 Shell 脚本实现

以下脚本整合了Git 代码拉取、作业提交、实时日志监控、超时控制功能,可直接用于生产环境。
1. 脚本完整代码

bash
#!/bin/bash
set -euo pipefail# ==============================================
# 基础配置(根据实际环境修改)
# ==============================================
CARTE_HOST="localhost"       # Carte服务IP(本地填localhost)
CARTE_PORT="8303"            # Carte服务端口(默认8303)
CARTE_USER="cluster"         # Carte认证用户名(默认cluster)
CARTE_PWD="cluster"          # Carte认证密码(默认cluster)
WORK_DIR="/home/kettle/fss-data-model"  # Git代码工作目录
JOB_PATH="/home/kettle/fss-data-model/kettle_script/JOB_PROCESS_BATCH.kjb"  # 作业文件路径
PARAM1="excel_abb=ltd"       # 作业参数1(根据实际需求添加)
PARAM2="db_user=sflcgood"    # 作业参数2(根据实际需求添加)# 日志查询配置
CHECK_INTERVAL=0.2            # 日志查询间隔(秒)
MAX_WAIT_SECONDS=3600        # 最大等待时间(秒,防止无限等待)# ==============================================
# 步骤1:拉取Git最新代码(容错处理)
# ==============================================
echo "=== 步骤1:拉取Git最新代码 ==="
cd "$WORK_DIR" || {echo "ERROR:Git工作目录 $WORK_DIR 不存在!"exit 1
}# Git拉取失败时不中断脚本,继续使用本地文件
if ! git pull; thenecho "WARNING:Git拉取失败,可能是网络问题或权限不足,继续使用本地文件执行..."
fi# ==============================================
# 步骤2:提交作业到Carte服务(核心步骤)
# ==============================================
echo -e "\n=== 步骤2:提交Job到Carte服务 ==="
# 通过POST请求提交作业,携带认证信息和参数
RESPONSE=$(curl -s -X POST \"http://${CARTE_HOST}:${CARTE_PORT}/kettle/executeJob/" \-u "${CARTE_USER}:${CARTE_PWD}" \-d "job=${JOB_PATH}" \-d "param:${PARAM1}" \-d "param:${PARAM2}")# 从Carte返回结果中提取作业ID(正则匹配<id>标签内容)
JOB_ID=$(echo "$RESPONSE" | grep -oP '<id>\K[^<]+' | tr -d '[:space:]')# 校验作业ID是否获取成功
if [ -z "$JOB_ID" ]; thenecho "ERROR:提交作业失败!Carte服务返回内容:"echo "$RESPONSE"exit 1
fi
echo "SUCCESS:作业提交成功!Job ID = ${JOB_ID}"# ==============================================
# 步骤3:实时监控作业日志,直到执行结束
# ==============================================
echo -e "\n=== 步骤3:实时监控作业日志(Job ID: ${JOB_ID}) ==="
echo "作业执行中,每${CHECK_INTERVAL}秒刷新一次日志,最大等待时间${MAX_WAIT_SECONDS}秒..."# 从作业路径中自动提取作业名称(如JOB_PROCESS_BATCH.kjb → JOB_PROCESS_BATCH)
JOB_NAME=$(echo "$JOB_PATH" | awk -F '/' '{print $NF}' | sed 's/\.kjb$//')
echo "自动识别作业名称:${JOB_NAME}"# 初始化监控参数
START_TIME=$(date +%s)       # 作业开始时间(时间戳)
LAST_LOG_LINE=0              # 已读取的日志行数(避免重复打印)
IS_COMPLETE=0                # 作业是否完成(0:未完成,1:已完成)# 循环查询日志,直到作业完成或超时
while [ $IS_COMPLETE -eq 0 ]; do# 1. 检查是否超时CURRENT_TIME=$(date +%s)ELAPSED_TIME=$((CURRENT_TIME - START_TIME))if [ $ELAPSED_TIME -ge $MAX_WAIT_SECONDS ]; thenecho -e "\nERROR:作业执行超时(超过${MAX_WAIT_SECONDS}秒),可能存在死锁或资源不足!"exit 1fi# 2. 调用Carte接口查询日志(仅获取新增日志)RESPONSE=$(curl -s -u "${CARTE_USER}:${CARTE_PWD}" \"http://${CARTE_HOST}:${CARTE_PORT}/kettle/jobStatus/?name=${JOB_NAME}&id=${JOB_ID}&from=${LAST_LOG_LINE}")# 3. 提取作业当前状态(Finished/Stopped/Running)STATUS=$(echo "$RESPONSE" | grep -oP '(?<=id="statusColor" style="font-weight: bold;">)[^<]+')# 4. 提取新增日志(从LAST_LOG_LINE之后开始)NEW_LOGS=$(echo "$RESPONSE" | awk -v start="$LAST_LOG_LINE" 'BEGIN { in_log=0; log_line=0 }/<textarea id="joblog"/ { in_log=1; next }  # 进入日志区域/<\/textarea>/ { in_log=0 }                  # 退出日志区域in_log {log_line++if (log_line > start) print                # 只打印新增日志}')# 5. 输出新增日志(非空时打印)if [ -n "$NEW_LOGS" ]; thenecho "$NEW_LOGS"# 更新已读取的日志行数(下次从新行数开始查询)LAST_LOG_LINE=$(echo "$RESPONSE" | awk 'BEGIN { in_log=0; log_line=0 }/<textarea id="joblog"/ { in_log=1; next }/<\/textarea>/ { in_log=0 }in_log { log_line++ }END { print log_line }')fi# 6. 判断作业是否完成case "$STATUS" in"Finished")echo -e "\n=== 作业执行成功 ==="echo "最终状态:${STATUS}"echo "总耗时:${ELAPSED_TIME}秒"IS_COMPLETE=1;;"Stopped")echo -e "\n=== 作业执行失败 ==="echo "最终状态:${STATUS}(可能是脚本错误或数据问题)"echo "总耗时:${ELAPSED_TIME}秒"IS_COMPLETE=1exit 1  # 失败时退出码设为1,便于调度系统识别;;*)# 未完成则等待指定间隔后继续查询sleep $CHECK_INTERVAL;;esac
done

2. 脚本核心功能说明

功能模块实现逻辑解决的问题
Git 代码拉取git pull + 容错处理,拉取失败时继续使用本地文件避免网络波动导致脚本中断,提高稳定性
作业提交与 ID 提取通过curl POST提交作业,正则匹配标签提取 Job ID自动获取作业唯一标识,无需手动查询
作业名称自动识别从作业路径(如JOB_PROCESS_BATCH.kjb)中截取名称,避免硬编码适配不同作业名称,提高脚本通用性
实时日志监控按CHECK_INTERVAL间隔查询日志,仅打印新增内容,记录已读行数避免重复日志刷屏,实时跟踪执行进度
超时控制计算作业执行时间,超过MAX_WAIT_SECONDS时强制退出防止作业卡死导致脚本无限等待,释放资源
状态判断与失败处理识别Finished(成功)/Stopped(失败)状态,失败时返回非 0 退出码便于集成到 Airflow、Crontab 等调度系统,实现失败告警

四、脚本使用与部署

1. 环境准备
Kettle Carte 服务启动:确保 Carte 服务已在指定端口(如 8303)运行,配置文件(carte-config.xml)中认证用户密码与脚本一致(默认cluster:cluster);
创建carte-config.xml

cd /path/to/data-integration
vi carte-config.xml

carte-config.xml文件内容:

<slave_config><!-- 核心服务器配置(修正标签和认证信息) --><slaveserver><name>SimpleCarte</name><hostname>0.0.0.0</hostname>  <!-- 正确标签:hostname --><port>8303</port>             <!-- 目标端口 --><webapp>carte</webapp>        <!-- 上下文路径,与API路径匹配 --><username>cluster</username>  <!-- 认证用户名 --><password>cluster</password>  <!-- 认证密码 --><master>N</master>            <!-- 标记为从节点(非必须,视场景而定) --></slaveserver><!-- 可选:日志保留配置(避免作业日志被过早清理) --><max_log_timeout_minutes>1440</max_log_timeout_minutes>  <!-- 日志保留24小时 --><object_timeout_minutes>1440</object_timeout_minutes>    <!-- 作业对象保留24小时 -->
</slave_config>

启动Carte服务(后台运行)

cd /path/to/data-integration
nohup ./carte.sh carte-config.xml > carte.log 2>&1 &

2. 执行脚本
运行脚本

./ltd_sjqy_carte.sh

3. 脚本输出示例

=== 步骤1:拉取Git最新代码 ===
Already up to date.

=== 步骤2:提交Job到Carte服务 ===
SUCCESS:作业提交成功!Job ID = 23093d93-d351-4432-ad00-c18af74e092e

=== 步骤3:实时监控作业日志(Job ID: 23093d93-d351-4432-ad00-c18af74e092e) ===
作业执行中,每5秒刷新一次日志,最大等待时间3600秒…
自动识别作业名称:JOB_PROCESS_BATCH
2025/09/18 10:48:59 - JOB_PROCESS_BATCH - 开始执行任务
2025/09/18 10:48:59 - JOB_PROCESS_BATCH - 开始项[获取表_列表]
2025/09/18 10:48:59 - 获取表_列表 - Using run configuration [Pentaho local]
…(中间日志省略)…
2025/09/18 10:49:04 - JOB_PROCESS_BATCH - 任务执行完毕

=== 作业执行成功 ===
最终状态:Finished
总耗时:5秒

五、常见问题排查

  1. 作业提交失败,无法获取 Job ID
    原因 1:Carte 服务未启动或端口错误;
    排查:netstat -tlnp | grep 8303 检查端口是否监听,ps -ef | grep carte 检查进程是否存在。
    原因 2:认证失败(用户名 / 密码错误);
    排查:核对carte-config.xml中节点的username和password,确保与脚本一致。
    原因 3:作业路径错误(文件不存在或权限不足);
    排查:ls -l $JOB_PATH 检查文件是否存在,chmod 755 $JOB_PATH 赋予执行权限。

  2. 日志查询返回 404 或空内容
    原因:未同时指定name(作业名称)和id(作业 ID);
    解决:脚本已自动提取作业名称,无需手动干预,若手动查询需携带两个参数:
    bash
    curl -u ‘cluster:cluster’ “http://localhost:8303/kettle/jobStatus/?name=JOB_PROCESS_BATCH&id=23093d93-d351-4432-ad00-c18af74e092e”
    这里问AI就一直问不出来,要不就是给我只有id,要么就是只给我只有name的,还有给我一堆排查的方法,完全就是瞎扯。后续还是我发给它语句,然后让它帮我改sh文件的。当然我是发了curl返回的结果给它的。

  3. 远程浏览器访问 Carte 卡顿
    原因:图形渲染依赖高,远程传输延迟大;
    解决:放弃图形界面,直接使用curl或脚本查询,效率提升 10 倍以上。图形渲染问题暂时无法解决,我用的是windTerm,使用x11打开的页面,火狐浏览器,非常卡,和AI说的渲染问题,我查了下:

[root@localhost script]# glxinfo | grep "OpenGL renderer"
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
OpenGL renderer string: Intel(R) Arc(TM) Graphics

AI回复的Intel Arc 显卡驱动与当前 Mesa 版本不兼容和 一些解决方法,不靠谱,也太想动服务器上的这些东西。不知道有没有哪位对linux和x11比较熟悉的大神给下思路和方法。

六、总结与扩展

本文提供的 Shell 脚本实现了 Kettle Carte 服务的全流程自动化,核心优势在于:
无图形依赖:完全通过命令行操作,避免远程浏览器卡顿问题;
高稳定性:包含 Git 拉取容错、超时控制、失败处理,适配生产环境;
易集成:支持与 Crontab、Airflow 等调度系统结合,实现定时执行与失败告警。
扩展方向
日志持久化:将作业日志写入文件(如/var/log/kettle/job_${JOB_ID}.log),便于后续审计;
邮件告警:作业失败时通过mailx发送告警邮件,包含失败日志;
多作业支持:将作业路径、参数配置为数组,实现批量提交与监控;
Docker 部署:将 Carte 服务与脚本打包为 Docker 镜像,实现环境一致性。
通过这套方案,可大幅提升 Kettle 作业的调度效率与稳定性,减少人工干预成本,适合中小型数据团队的 ETL 自动化建设。

制作不易,小手点赞和关注,感谢!

ps:
最近的开发,用了豆包帮忙写了很多代码,省了我好多工作。目前做的是数据开发的工作,此项目有建模,我用AI帮忙写了很多python代码(之前我做过java的开发,建议大家使用python,python在这方面上有浑天独厚的优势),解决了我很多建模工具上没有的功能。我对于AI的总结是,
1、沟通问题,和AI沟通是个大问题,我看很多人对于AI沟通说的不清楚,或者说他对原理不了解,不会说,这都是及其考研的。
2、人和AI,人应当是指挥者,领导的角色。AI在写的第一版代码往往是存在不少问题的,这个时候回应当指挥它改你错误的地方,或者是需要给指明逻辑。
3、对于不会写代码的人,想完全通过AI写程序,不现实,遇到问题根本不知道怎么指挥AI。
4、如果没有代码基础,看不懂AI写的代码,你就无法指挥它去改正真正的错误。如果没有充实的理论知识,当AI无法修复你的问题时,就无法给AI指明解决思路和方法,更是无法自己解决问题。

http://www.dtcms.com/a/388859.html

相关文章:

  • 【数字展厅】数字科技展厅是怎么建设沉浸式体验的?
  • 2025网安周|美创科技多地联动,共筑数据安全防线
  • 数字大健康:一场重塑未来的健康革命,正被科技重新定义
  • 手搓一个可以自动化对比yolo模型性能曲线的工具
  • 海图科技双撕裂检测装置:筑牢矿用皮带运输安全防线
  • 32、语言模型训练全流程:从数据到模型的工程化实现
  • 打造一款支持 Mermaid 与 ECharts 的 Markdown 编辑器:基于 Vditor 的实战指南
  • 《算法闯关指南:优选算法-双指针》--07三数之和,08四数之和
  • 华为显卡部署
  • Salesforce知识点:LWC(Lightning Web Components)面试题及答案
  • 【C/C++】一文通关C/C++内存管理:动态开辟改朝换代——new/delete
  • 安卓13_ROM修改定制化-----修改rom 实现“usb安装”选项默认开启
  • Git 常用命令速查表
  • Day45 51单片机UART串口通信与数码管时钟系统
  • 企业级图像AIGC技术观察:Seedream 4.0 模型能力与应用场景分析
  • Kurt-Blender零基础教程:第2章:建模篇——第2节:什么是修改器与建模马拉松
  • fbx 导入到 blender 出现很多黑色虚线的解决方法
  • 记力扣.2779 数组的最大美丽值 练习理解
  • Day26_【深度学习(6)—神经网络NN(2)前向传播的搭建案例】
  • 古老的游戏之竞技体育
  • CURSOR平替(deepseek+VScode)方案实现自动化编程
  • java对电子发票是否原件的快速检查
  • 贪心算法应用:顶点覆盖问题详解
  • Odoo中非库存商品的高级自动化采购工作流程
  • 缺少自动化测试会对 DevOps 带来哪些风险
  • 深入解析 Python 中的 __pycache__与字节码编译机制
  • SEO 优化:元数据 (Metadata) API 和站点地图 (Sitemap) 生成
  • postman+Jenkins进行API automation集成
  • 【算法磨剑:用 C++ 思考的艺术・单源最短路收官】BF/SPFA 负环判断模板 + 四大算法全总结
  • Flink的介绍及应用