转载自刘茫茫看山
问题背景
某天我们的租户反馈数据库连接缺少必要的驱动,我们通过日志查看确实是缺少部分数据库的驱动,因为DolphinScheduler默认只带了Oracle和MySQL的驱动,并且需要将pom文件中的test模式去掉才可以在打包的时候引入。我们的任务量比较大,在3.0存在容错机制的情况下,重启Master和Worker时,任务会重复容错多次,对用户使用很不友好,对Yarn集群的压力也比较大,所以非必要不会重启服务,这就需要在不重启的前提下加载新的驱动包。
遇到的问题
当开始做的时候,想的过于简单,下面是Worker模块下的启动命令,libs目录后面加载的是*,所以我们认为程序肯定会自动加载jar。
但是当我们将jar放到对应的目录后,重启测试数据库连接,发现还是报了和之前一样的问题。
Could not load driverClass oracle.jdbc.driver.OracleDriver
我们需要了解java.class.path为什么没有将我们新添加的驱动包加载进去,于是我们找出了worker服务的进程id,并通过jinfo命令查看类路径的加载情况,发现java.calss.path
对应的目录从*变成了jar包的绝对路径,我们新添加的jar的绝对路径没有在里面,所以不会读取驱动。
解决方法
我们最熟悉的类加载模式就是双亲委派机制,在类加载模式中存在一个ExtensioinClassloader
类,它是java.lang.ClassLoader
的子类,该类加载器负责加载Java的扩展库JAVA_HOME/jre/lib/ext/*.jar
或者java.ext.dirs
路径下的内容。
我们通过jinfo命令查看进程中的扩展目录,发现java.ext.dirs
对应的值不是绝对路径,也就表示我们可以尝试通过将额外的驱动jar包放到扩展目录中加载。
这里以Oracle驱动为例,通过将Oracle驱动jar放到对应的扩展目录中,测试数据源连接情况,连接成功,希望可以给有需要的小伙伴提供有价值的参考。
本文由 白鲸开源科技 提供发布支持!