Flink加载自定义Jar包

背景

用户只需要编写Fink SQ就可以快速构建实时计算任务,通过yarn session模式试运行或者语法校验需要自定义udf,其中用户可以通过上传Jar包的方式支持自定义函数UDF,这里就需要在启动作业的时候能够动态加载自定义Jar包。

解决

Flink 官方文档可以招待找到关于 pipeline.classpath 参数配置的描述,通过该配置项来加载classpath。yarn的api并没有提供该配置项目的参数入口,所以在作业的 main 函数中直接通过反射获取 Configuration 对象,并且直接设置 pipeline.classpaths 的值。

private static void loadPipelineClassPaths(StreamExecutionEnvironment env, List<String> jarList) throws Exception{
        Field configuration = StreamExecutionEnvironment.class.getDeclaredField("configuration");
        configuration.setAccessible(true);
        Configuration o = (Configuration)configuration.get(env);
 
        Field confData = Configuration.class.getDeclaredField("confData");
        confData.setAccessible(true);
        Map<String,Object> temp = (Map<String,Object>)confData.get(o);
        temp.put("pipeline.classpaths", jarList);
 }

同时还需要在作业的 main 方法里动态加载Jar包到 URLClassloader里:

public static void loadJar(URL jarUrl) {
        //从URLClassLoader类加载器中获取类的addURL方法
        Method method = null;
        try {
            method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
        } catch (NoSuchMethodException | SecurityException e1) {
            e1.printStackTrace();
        }
        assert method != null;
        boolean accessible = method.isAccessible();
        try {
            if (!accessible) {
                method.setAccessible(true);
            }
            URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
            method.invoke(classLoader, jarUrl);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            method.setAccessible(accessible);
        }
  }

-C参数使用的类加载进行加载与user jar是一个类加载器,taskManager运行的时候会加载并且相应的job停止时自动卸载,同时每个job都会有自己的ClassLoader实现相互隔离。希望Flink 后续版能够在Rest API 层面能够直接提供参数来加载用户自定义的Jar包,并且能够直接读取HDFS文件来加载Jar包。

暂时将用户自定义的Jar包上传到hdfs并获取到hdfs的http连接地址,形式如下:
http://hadoop1:50070/webhdfs/v1/test.jar?op=OPEN&namenoderpcaddress=nnCluster&offset=0
对hdfs高可用场景,可以通过如下方式获取到active节点连接地址:

public static String getActiveHttpPath(Hdfs hdfsCon) throws IOException {
        HdfsFileSystem hdfsFileSystem = SpringUtils.getBean(HdfsFileSystem.class);
        InetSocketAddress active = HAUtil.getAddressOfActive(hdfsFileSystem.getHdfs(hdfsCon));
        String httpPath = "http://" + active.getAddress().getHostAddress() + ":50075/webhdfs/v1";
        return httpPath;
 }

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Flink支持动态加载Jar包,可以在运行时动态添加、移除Jar包,以便于实时更新应用程序。下面是一个简单的示例: 1. 创建一个Flink应用程序,例如WordCount,打Jar包。 2. 在Flink集群中启动一个JobManager和一个或多个TaskManager。 3. 使用Flink提供的命令行工具flink run启动WordCount应用程序,例如: ``` flink run -c com.example.WordCount /path/to/wordcount.jar ``` 4. 在运行WordCount应用程序时,可以使用Flink提供的REST API或Web界面动态添加或移除Jar包。例如,可以使用以下REST API请求动态添加Jar包: ``` POST /jars/upload Content-Type: multipart/form-data Upload-Jar: true <file upload> ``` 注意,需要将Upload-Jar头设置为true,以便告诉Flink上传的文件是Jar包。 5. 添加Jar包后,可以使用Flink提供的REST API或Web界面启动新的作业,并使用新添加的Jar包。例如,可以使用以下REST API请求启动新的作业: ``` POST /jobs Content-Type: application/json { "jarPath": "/jars/myjar.jar", "className": "com.example.MyJob", "args": ["arg1", "arg2"] } ``` 这将启动一个新的作业,使用新添加的Jar包,并调用MyJob类的main方法,传递arg1和arg2参数。 注意,需要将jarPath设置为新添加的Jar包的路径,而不是原始的WordCount应用程序的路径。 6. 移除Jar包时,可以使用Flink提供的REST API或Web界面删除Jar包。例如,可以使用以下REST API请求删除Jar包: ``` DELETE /jars/myjar.jar ``` 这将删除名为myjar.jarJar包,如果有作业正在使用该Jar包,则会在作业完成后删除Jar包。 总之,Flink的动态Jar包加载功能非常强大,可以帮助用户实现实时更新应用程序的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风卷残尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值