You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GCP Dataproc Serverless加载MS SQL JDBC驱动失败求助

问题描述

我用Spring Boot编写了一个Java Spark作业,需要在启动Spark操作前调用MS SQL数据库获取配置属性/值。本地环境中,我通过在Spark额外类路径传入驱动类的方式可正常运行该作业。

我尝试通过Dataproc环境变量spark.dataproc.driverEnv.SPARK_EXTRA_CLASSPATH设置额外类路径,配置为SPARK_EXTRA_CLASSPATH=gs://XXXX/XXXX/mssql-jdbc-12.2.0.jre11.jar,日志中也显示了该路径,但仍出现错误:

Caused by: java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver.

错误详情:

Caused by: java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    at com.zaxxer.hikari.HikariConfig.setDriverClassName(HikariConfig.java:318)

相关代码:

public DataSource getDataSource() {
    DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
    dataSourceBuilder.driverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
    dataSourceBuilder.username(config.getSqlUser());
    dataSourceBuilder.password(config.getSqlPass());
    dataSourceBuilder.url(config.getSqlUrl());
    return dataSourceBuilder.build();
  }

请问是否有无需创建自定义镜像,仅通过额外类路径将依赖库添加到默认容器中的解决方案?


解决方案

以下几种方法可在不创建自定义镜像的前提下解决问题:

  • 提交作业时用--jars参数指定驱动
    直接在提交Spark作业时,把MS SQL驱动的GCS路径和你的应用Jar包一起传入--jars参数,该参数会自动将Jar包添加到driver和executor的类路径中:

    gcloud dataproc jobs submit spark \
        --cluster=你的集群名称 \
        --class=你的主类全路径 \
        --jars=gs://XXXX/XXXX/mssql-jdbc-12.2.0.jre11.jar,你的应用Jar包GCS路径 \
        --region=你的集群区域
    

    多个Jar包用逗号分隔即可。

  • 设置Spark专属类路径属性
    在提交作业时直接配置spark.driver.extraClassPath和spark.executor.extraClassPath属性,明确指定驱动Jar包路径:

    gcloud dataproc jobs submit spark \
        --cluster=你的集群名称 \
        --class=你的主类全路径 \
        --properties=spark.driver.extraClassPath=gs://XXXX/XXXX/mssql-jdbc-12.2.0.jre11.jar,spark.executor.extraClassPath=gs://XXXX/XXXX/mssql-jdbc-12.2.0.jre11.jar \
        --jar=你的应用Jar包GCS路径 \
        --region=你的集群区域
    

    这种方式绕过环境变量的加载时机问题,直接把驱动Jar包注入到Spark的类加载逻辑中。

  • 通过初始化动作将驱动复制到集群本地类路径
    如果集群长期需要使用该驱动,可以编写初始化脚本把GCS上的驱动Jar包复制到集群节点的/usr/lib/spark/jars目录(Spark默认扫描的类路径目录):

    1. 编写初始化脚本copy-mssql-driver.sh:
      #!/bin/bash
      gsutil cp gs://XXXX/XXXX/mssql-jdbc-12.2.0.jre11.jar /usr/lib/spark/jars/
      
    2. 创建集群时指定该初始化动作:
      gcloud dataproc clusters create 你的集群名称 \
          --region=你的集群区域 \
          --initialization-actions=gs://你的脚本存储路径/copy-mssql-driver.sh
      

    后续所有提交到该集群的Spark作业都会自动加载这个驱动Jar包。

之前用spark.dataproc.driverEnv.SPARK_EXTRA_CLASSPATH不生效的原因是:该环境变量是设置给driver进程的系统环境变量,但Spark的类路径初始化逻辑可能在环境变量生效前就已完成,导致驱动类未被加载到正确路径。上面的方法都是直接针对Spark的类路径配置,能确保驱动Jar包被正确识别。

内容的提问来源于stack exchange,提问作者Baskar Gopal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 02:30:01