flink 作业报日志类冲突的解决方案

文章目录

背景

实时作业在页面提交任务后,报NoSuchMethodException 方法,看了下是关于log4j的,首先是作业升级了很多依赖的版本,其次flink 也升级 到了1.19版本

思考

  • 打的Jar有bug?
    先想了一下是不是打的Jar有问题,后面想了下如果Jar有问题是类找不到才对
  • 类冲突才对?
    观察了一下

业务代码

flink 自带的日志类

结论,很明显版本不一样

初步解决方案

  • 实时作业代码日志jar 降级

    我先想到的解决方案是实时作业代码日志jar 降级,细看了一些实时里有很多依赖,而且是升级到java 21的,不好处理

  • flink 本身 日志jar 升级

    尝试了下把报冲突的jar类升到了2.20的版本,服务启动不了,直接报错

    然后尝试了下把其它日志类都升到了2.20的版本,服务可以启动,作业也可以正常提交,好像这里事情已经解决,但是我再看了一下,发现flink 自身的日志打印有总是,所有日志都没能正常打印

  • 插件的方法把类重新命名?

    这个方法不行,太多地方引用这个类了

似乎陷入了死胡同 ? 好像没招了,常用的这些方法都不行

深入思考下

回到问题本身,从第一性原理的角度出来想一下

  • 为啥相同的类是加载的flink lib 目录下的jar,而不是实时作业的呢?
    flink 本身实现了ChildFirstClassLoader ,默认是先加载用户代码里的class,如果没有加载到,再从其它地方加载,那理论上不应该有这个问题

打开源码看下

bash 复制代码
 @Override
    protected Class<?> loadClassWithoutExceptionHandling(String name, boolean resolve)
            throws ClassNotFoundException {

        // First, check if the class has already been loaded
        Class<?> c = findLoadedClass(name);

        if (c == null) {
            // check whether the class should go parent-first
            for (String alwaysParentFirstPattern : alwaysParentFirstPatterns) {
                if (name.startsWith(alwaysParentFirstPattern)) {
                    return super.loadClassWithoutExceptionHandling(name, resolve);
                }
            }

            try {
                // check the URLs
                c = findClass(name);
            } catch (ClassNotFoundException e) {
                // let URLClassLoader do it, which will eventually call the parent
                c = super.loadClassWithoutExceptionHandling(name, resolve);
            }
        } else if (resolve) {
            resolveClass(c);
        }

        return c;
    }
bash 复制代码
 if (name.startsWith(alwaysParentFirstPattern)) {

上面这段引起了我的注意,有一些类是由AppClassLoader 加载的,顺藤摸瓜

发现了有这些类,发现也没有log4j的呀,差点看漏了,

还有这个变量的,终于发现了,原来在这,那看来找到了问题所在的地方

bash 复制代码
   @Internal
    public static final String[] PARENT_FIRST_LOGGING_PATTERNS =
            new String[] {
                "org.slf4j",
                "org.apache.log4j",
                "org.apache.logging",
                "org.apache.commons.logging",
                "ch.qos.logback"
            };

终极解决方案

既然问题找到了,那最简单的是就是把这个配置的默认值修改下,修改config.yaml,服务启动,作业提交成功。 各方法都正常,问题解决

总结

  • 可以想下为啥flink 要把那些类让AppClassLoader去加载
  • 为啥要设计ChildFirstClassLoader
相关推荐
StarRocks_labs1 小时前
从InfluxDB到StarRocks:Grab实现Spark监控平台10倍性能提升
大数据·数据库·starrocks·分布式·spark·iris·物化视图
董可伦2 小时前
Dinky 安装部署并配置提交 Flink Yarn 任务
android·adb·flink
若兰幽竹2 小时前
【Spark分析HBase数据】Spark读取并分析HBase数据
大数据·spark·hbase
R²AIN SUITE2 小时前
金融合规革命:R²AIN SUITE 如何重塑银行业务智能
大数据·人工智能
绿算技术3 小时前
“强强联手,智启未来”凯创未来与绿算技术共筑高端智能家居及智能照明领域新生态
大数据·人工智能·智能家居
只因只因爆4 小时前
spark的缓存
大数据·缓存·spark
Leo.yuan5 小时前
3D 数据可视化系统是什么?具体应用在哪方面?
大数据·数据库·3d·信息可视化·数据分析
只因只因爆6 小时前
spark小任务
大数据·分布式·spark
cainiao0806056 小时前
Java 大视界——Java 大数据在智慧交通智能停车诱导系统中的数据融合与实时更新
java·大数据·开发语言
End9289 小时前
Spark之搭建Yarn模式
大数据·分布式·spark