DATAX_HOOK,怎么实现的

2023-10-30

DATAX_HOOK,怎么实现的


JobContainer 类Datax的job执行类。

// JobContainer 类
// An highlighted block
// JobContainer 类关于
finally {
            if (!isDryRun) {

                this.destroy();
                this.endTimeStamp = System.currentTimeMillis();
                if (!hasException) {
                    //最后打印cpu的平均消耗,GC的统计
                    VMInfo vmInfo = VMInfo.getVmInfo();
                    if (vmInfo != null) {
                        vmInfo.getDelta(false);
                        LOG.info(vmInfo.totalString());
                    }                   LOG.info(PerfTrace.getInstance().summarizeNoException());
                    this.logStatistics(jobStatistics);
                    DirtyRecordContext.clear();
                    //这里就是调用Hook
                    this.invokeHooks();
                }
            }
        }

invokeHooks 方法。

// invokeHooks 方法
// An highlighted block
/**
     * 调用外部hook
     */
    private void invokeHooks() {
        Communication comm = super.getContainerCommunicator().collect();
        //这里就是存放实现hook接口的class类
        HookInvoker invoker = new HookInvoker(CoreConstant.DATAX_HOME + "/hook", configuration, comm.getCounter(), jobStatistics);
        invoker.invokeAll();
    }

invokeAll方法 。

//invokeAll方法 。
// An highlighted block
public void invokeAll() {
        if (!baseDir.exists() || baseDir.isFile()) {//这里就是判断/hook文件夹下面有没有class文件,这class文件就是Hook接口的实现类
            LOG.info("No hook invoked, because base dir not exists or is a file: " + baseDir.getAbsolutePath());
            return;
        }

        String[] subDirs = baseDir.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return new File(dir, name).isDirectory();
            }
        });

        if (subDirs == null) {
            throw DataXException.asDataXException(FrameworkErrorCode.HOOK_LOAD_ERROR, "获取HOOK子目录返回null");
        }
        
        for (String subDir : subDirs) {
        	//实际上就是这里调用
            doInvoke(new File(baseDir, subDir).getAbsolutePath());
        }
    }

doInvoke方法。

doInvoke方法
Class文件实现 HooK接口里面的 invoke 方法
/**
     * 遍历path路径下的所有jar文件,解析。这些jar包里的class都是hook的实现类,然后执行invoke实现方法
     * 好处:可以无限制的添加hook的实现类
     * @param path
     */
    private void doInvoke(String path) {
        ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
        try {
        	//根据path(文件夹里面的jar,包含hook实现类的class,以及相关的依赖的jar包),获取实现类的class
            JarLoader jarLoader = new JarLoader(new String[]{path});
            //JarLoader 是继承与 URLClassLoader,这个类的作用就是根据路径读取jar包
            //这一步是为了把读取的jar包,加入到jvm里面
            Thread.currentThread().setContextClassLoader(jarLoader);
            Iterator<Hook> hookIt = ServiceLoader.load(Hook.class).iterator();
            if (!hookIt.hasNext()) {
                LOG.warn("No hook defined under path: {}", path);
            } else {
                while (hookIt.hasNext()) {
                    Hook hook = hookIt.next();
                    LOG.info("Invoke hook [{}], path: {}", hook.getName(), path);
                    hook.invoke(conf, msg, jobStatistics);
                }
            }
        } catch (Exception e) {
            LOG.error("Exception when invoke hook");
            throw DataXException.asDataXException(
                    CommonErrorCode.HOOK_INTERNAL_ERROR, "Exception when invoke hook", e);
        } finally {
            Thread.currentThread().setContextClassLoader(oldClassLoader);
        }
    }

Hook的接口

// Hook的接口
public interface Hook {

    /**
     * 返回名字
     *
     * @return
     */
    public String getName();

    /**
     * TODO 文档
     *
     * @param jobConf
     * @param msg
     * @param jobStatistics Datax job监控信息
     */
    void invoke(Configuration jobConf, Map<String, Number> msg, JobStatistics jobStatistics);

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DATAX_HOOK,怎么实现的 的相关文章

  • Java:无法从同一包中的不同类访问静态变量

    这很奇怪 因为我有一个可以访问 Frame dimension getWidth 的 Character 类 及其伙伴 getHeight 但是当我想在 Map 类中使用它时 Eclipse 强调了它并且无法给我反馈 运行该程序最终会出现
  • 如何在 Firebase 远程配置中从 JSON 获取值

    我是 Android 应用开发和 Firebase 的新手 我想知道如何获取存储在 Firebase 远程配置中的 JSONArray 文件中的值 String 和 Int 我使用 Firebase Remote Config 的最终目标是
  • JVisualVM/JConsole 中的 System.gc() 与 GC 按钮

    我目前正在测试处理 XML 模式的概念验证原型 并围绕一个非常消耗内存的树自动机外部库 我已经获得了源代码 构建 我想绘制 真实峰值 堆 随着模式大小的增加 不同运行的内存消耗 使用的指标符合我的目的并且不会影响问题 或者至少是它的合理近似
  • 是否有任何简单(且最新)的 Java 框架可用于在 Swing 应用程序中嵌入电影?

    我正在构建一个小型 Swing 应用程序 我想在其中嵌入一部电影 重要的是 这个应用程序是一个 WebStart 应用程序 并且该库应该能够打包在我启动的 jnlp 中 即 不依赖于本机库 我知道并尝试过 JMF 但我认为与其他框架相比 其
  • Spring Data JPA 选择不同

    我有一个情况 我需要建立一个select distinct a address from Person a 其中地址是 Person 内的地址实体 类型的查询 我正在使用规范动态构建我的 where 子句并使用findAll Specifi
  • Spring Boot自动装配存储库始终为空[重复]

    这个问题在这里已经有答案了 每次我进入我的服务类时 存储库似乎都没有自动连接 因为它不断抛出 NullPointerException 谁能帮我检查一下我缺少什么吗 这是我的代码 演示应用程序 java package com exampl
  • org.hibernate.QueryException:无法解析属性:文件名

    我正在使用休眠Criteria从列中获取值filename在我的桌子上contaque recording log 但是当我得到结果时 它抛出异常 org hibernate QueryException 无法解析属性 文件名 com co
  • 是否可以使用 Flying Saucer (XHTML-Renderer) 将 css 解析为类路径资源?

    我正在尝试将资源打包到 jar 中 但我无法让 Flying Saucer 在类路径上找到 css 我无法轻松构建 URL 来无缝解决此问题 https stackoverflow com questions 861500 url to l
  • 大数据使用什么数据结构

    我有一个包含一百万行的 Excel 工作表 每行有 100 列 每行代表一个具有 100 个属性的类的实例 列值是这些属性的值 哪种数据结构最适合在这里使用来存储数百万个数据实例 Thanks 这实际上取决于您需要如何访问这些数据以及您想要
  • ConcurrentHashMap 内部是如何工作的?

    我正在阅读有关 Java 并发性的 Oracle 官方文档 我想知道Collection由返回 public static
  • 使用 Guice 优化注册表

    你好 今天思考了一种优化 有一些疑问 语境 我正在使用 Guice 2 进行 Java 开发 在我的网络应用程序中 我有一个转换器注册表 可以即时转换为某种类型 转换器描述如下 public class StringToBoolean im
  • Java:如何为山区时间创建 TimeZone 对象?

    必须不禁用夏令时 嗯 在这个清单 http en wikipedia org wiki List of tz database time zones在 zoneinfo 时区名称中 有很多声称是 山地时间 找到最适合您想要的那个 然后使用它
  • 使用 Mockito 模拟某些方法,但不模拟其他方法

    有没有办法使用 Mockito 模拟类中的某些方法 而不模拟其他方法 例如 在这个 诚然是人为的 Stock我想嘲笑的班级getPrice and getQuantity 返回值 如下面的测试片段所示 但我想要getValue 执行乘法 如
  • QuerySyntaxException:无法找到类

    我正在使用 hql 生成 JunctionManagementListDto 类的实际 Java 对象 但我最终在控制台上出现以下异常 org hibernate hql internal ast QuerySyntaxException
  • 如何在 Java 中创建接受多个值的单个注释

    我有一个名为 Retention RetentionPolicy SOURCE Target ElementType METHOD public interface JIRA The Key Bug number JIRA referenc
  • java库维护数据库结构

    我的应用程序一直在开发 所以偶尔 当版本升级时 需要创建 更改 删除一些表 修改一些数据等 通常需要执行一些sql代码 是否有一个 Java 库可用于使我的数据库结构保持最新 通过分析类似 db structure version 信息并执
  • JMenu 中的文本居中

    好吧 我一直在网上寻找有关此问题的帮助 但我尝试的任何方法似乎都不起作用 我想让所有菜单文本都集中在菜单按钮上 当我使用setHorizontalTextPosition JMenu CENTER 没有变化 事实上 无论我使用什么常量 菜单
  • Hamcrest Matchers - 断言列表类型

    问题 我目前正在尝试使用 Hamcrest Matchers 来断言返回的列表类型是特定类型 例如 假设我的服务调用返回以下列表 List
  • 如何使用play框架上传多个文件?

    我在用play framework 2 1 2 使用java我正在创建视图来上传多个文件 我的代码在这里 form action routes upload up enctype gt multipart form data
  • 配置“DataSource”以使用 SSL/TLS 加密连接到 Digital Ocean 上的托管 Postgres 服务器

    我正在尝试托管数据库服务 https www digitalocean com products managed databases on 数字海洋网 https en wikipedia org wiki DigitalOcean 创建了

随机推荐

  • AngularJS 发送POST请求到后台

    这两个周公司要换前端框架 采用Ionic AngularJS来展示App 原来的App采用的是H5做的 说是H5用户体验不怎么好 所以叫我调研下 说真的 刚开始真的是一脸懵逼 找各种资料 论坛 视频 看了很多博客 很多大牛都说学习Ionic
  • 决策树算法的核心思想

    本文来自 公众号 自然语言处理与机器学习 作者 忆臻 一 算法思想 决策树 decision tree 是一个树结构 可以是二叉树或非二叉树 其每个非叶节点表示一个特征属性上的测试 每个分支代表这个特征属性在某个值域上的输出 而每个叶节点存
  • Prompt工程师指南[应用篇]:Prompt应用、ChatGPT

    1 ChatGPT Prompt Engineering 主题 与 ChatGPT 对话 Python 笔记本 ChatGPT介绍 ChatGPT是OpenAI训练的一种新型模型 可以进行对话交互 该模型经过训练 可以按照提示中的指令 在对
  • 获取顺序栈的栈顶元素

    转至 http www nowamagic net librarys veda detail 2276 获取顺序栈的栈顶元素 GetTop S e 若栈存在且非空 用e返回S的栈顶元素 参考之前线性表的话 就是设一个存储栈顶的变量 e 然后
  • 18、INSERT:插入数据(添加数据)

    数据库与表创建成功以后 需要向数据库的表中插入数据 在 MySQL 中可以使用 INSERT 语句向数据库已有的表中插入一行或者多行元组数据 基本语法 INSERT 语句有两种语法形式 分别是 INSERT VALUES 语句和 INSER
  • 实现打怪得分效果。(Unity)

    首先创建一个Text文本UI组件 并且通过锚点进行文本位置的摆放 并通过修改下面箭头处的值调整Text文本的大小和颜色 如果有字体也可以修改字体样式 也可以在添加组件处添加一个shadow组件修改x和y的值 使文本具有立体和阴影感看起来更有
  • STM32——蓝牙模块HC06

    STM32 蓝牙模块HC06 选用的芯片是STM32F407的芯片 一个HC06的蓝牙模块 我们采用串口连接 所以我们在芯片原理图找出串口模块 参数 STM32串口异步通信定义的参数传送格式 起始位 数据位 8位或者9位 奇偶校验位 第9位
  • 第二章 计算机发展与应用

    计算机从诞生至今已经经历了多个阶段的发展 包括 1 电子管时代 1940年代 1950年代 计算机使用电子管作为主要的电子元件 这些计算机体积庞大 功耗大 但是它们标志着计算机的诞生 并且在二战期间被广泛应用于军事领域 2 晶体管时代 19
  • 6.2、客户/服务器方式(C/S)&对等方式(P2P方式)

    网络应用程序运行在处于网络边缘的不同的端系统上 通过彼此间的通信来共同完成某项任务 开发一种新的网络应用首先要考虑的问题就是 网络应用程序在各种端系统上的组织方式和它们之间的关系 color red 网络应用程序在各种端系统上的组织方式和它
  • TypeScript与Date类型

    js的继承方式 经典的js寄生组合式继承 function MyDate Date apply this arguments this abc 1 function inherits subClass superClass function
  • mysql5.7.17安装+mysql error:1524+1045+外部访问出错

    1 mysql5 7 17安装 windows10系统 下载mysql 5 7 17 winx64 copymysql 5 6 35 winx64的data文件 进入安装数据库目录bin cd C ProgramFiles mysql 5
  • 指数历年各月涨幅分析-验证五穷六绝七翻身是否可信

    指数通常反映了一个行业或者一类股票的行情数据 本文将对697支指数的历史各月涨幅进行分析 为量化投资作一个参考 从分析中 我们可以验证五穷六绝七翻身是否可信 并找出上涨概率最大的一些指数和月份 1 数据准备 本文程序中用到两个数据 1 in
  • clickHouse MergeTree核心原理

    1 MergeTree的创建方式与存储结构 1 1 MergeTree的创建方式 CREATE TABLE IF NOT EXISTS db table name ON CLUSTER cluster name1 type1 DEFAULT
  • C# 基础程序结构和入门实例(学习心得 2)

    超级小白友好 讲解C 基础 每集5分钟轻松学习 拒绝从入门到放弃 C Hello World 实例 C 最小的程序结构需要包含以下部分 命名空间声明 一个 class 一个 Class 方法 该 Class 方法的属性 一个 Main 方法
  • python中class的作用

    在 Python 中 class 是用来定义对象的类型的 通过定义类 可以创建该类型的多个实例 每个实例都有相同的属性和方法 类也可以继承其它类 并扩展或重写属性和方法
  • 人工智能:未来制胜之道

    在数据 算法 计算 场景驱动新一轮人工智能飞速发展 未来3 5年内人工智能将处于服务智能阶段 即技术边际突破但应用海量拓展 人工智能未来竞争格局将由生态构建者 技术算法驱动者 应用聚焦者 垂直行业先行者 基础设施提供者五类竞争定位模式主导
  • springgateway限流-令牌桶算法

    限流配置 参见 https blog csdn net forezp article details 85081162 https cloud spring io spring cloud gateway 2 2 x reference h
  • 学计算机的感想300字,大学生计算机实训心得体会3篇

    大学生计算机实训心得体会3篇 我们有一些启发后 可以通过写心得体会的方式将其记录下来 这样我们可以养成良好的总结方法 那么心得体会到底应该怎么写呢 下面是小编为大家整理的大学生计算机实训心得体会 欢迎大家分享 大学生计算机实训心得体会1 在
  • 在服务器上下载安装anaconda

    anaconda下载与安装 1 连接到服务器 进入服务器界面 同时连上网络 登录到Anaconda官网 如果你的服务器是Linux系统 选择这一款 2 打开服务器的终端 Open in Terminal 进入命令行输入 bash Anaco
  • DATAX_HOOK,怎么实现的

    DATAX HOOK 怎么实现的 JobContainer 类Datax的job执行类 JobContainer 类 An highlighted block JobContainer 类关于 finally if isDryRun thi