本节主要介绍如何通过 GraalVM 的 native-image 组件构建 ShardingSphere-Proxy 的 Native Image 和对应的 Docker Image
。
server.yaml 的 conf 文件夹为 ./custom/conf,你可通过如下的 docker-compose.yml 文件进行测试。version: "3.8"
services:
apache-shardingsphere-proxy-native:
image: ghcr.io/apache/shardingsphere-proxy-native:latest
volumes:
- ./custom/conf:/opt/shardingsphere-proxy-native/conf
ports:
- "3307:3307"
若你发现构建过程存在缺失的 GraalVM Reachability Metadata, 应当在 https://github.com/oracle/graalvm-reachability-metadata 打开新的 issue , 并提交包含 ShardingSphere 自身或依赖的第三方库缺失的 GraalVM Reachability Metadata 的 PR。
ShardingSphere 的 master 分支尚未准备好处理 Native Image 中的单元测试,
需要等待 Junit 5 Platform 的集成,你总是需要在构建 GraalVM Native Image 的过程中,
加上特定于 GraalVM Native Build Tools 的 -DskipNativeTests 或 -DskipTests 参数跳过 Native Image 中的单元测试。
如下 3 个算法类由于涉及到 GraalVM Truffle Espresso 不方便在 host JVM 和 guest JVM 之间交互的 groovy.lang.Closure
类,暂未可在 GraalVM Native Image 下使用。
org.apache.shardingsphere.sharding.algorithm.sharding.complex.ComplexInlineShardingAlgorithmorg.apache.shardingsphere.sharding.algorithm.sharding.hint.HintInlineShardingAlgorithmorg.apache.shardingsphere.sharding.algorithm.sharding.inline.InlineShardingAlgorithm当前阶段,GraalVM Native Image 形态的 ShardingSphere Proxy 处于混合 AOT ( GraalVM Native Image ) 和 JIT ( GraalVM
Truffle Espresso ) 运行的阶段。由于 https://github.com/oracle/graal/issues/4555 尚未关闭,GraalVM Truffle Espresso
运行需要的 .so 文件并不会进入 GraalVM Native Image 内。因此如果你需要在 Docker Image 外运行 ShardingSphere Proxy
Native 的二进制文件,你需要确保系统环境变量 JAVA_HOME 指向 GraalVM 的 bin 目录,并且此 GraalVM
实例已经通过 GraalVM Updater 安装了 espresso 组件。
本节假定处于 Linux(amd64,aarch64), MacOS(amd64)或 Windows(amd64)环境。 如果你位于 MacOS(aarch64/M1) 环境,你需要关注尚未关闭的 https://github.com/oracle/graal/issues/2666 。
根据 https://www.graalvm.org/downloads/ 要求安装和配置 JDK 17 对应的 GraalVM CE 或 GraalVM EE。
同时可以通过 SDKMAN! 安装 JDK 17 对应的 GraalVM CE。
通过 GraalVM Updater 工具安装 native-image 和 espresso 组件。
根据 https://www.graalvm.org/22.3/reference-manual/native-image/#prerequisites 的要求安装本地工具链。
如果需要构建 Docker Image, 确保 docker-ce 已安装。
情形一:不需要使用存在 SPI 实现的 JAR 或第三方依赖的 JAR
在 Git Source 同级目录下执行如下命令, 直接完成 Native Image 的构建。
./mvnw -am -pl distribution/proxy-native -B -Pnative -DskipTests -Dmaven.javadoc.skip=true -Dcheckstyle.skip=true -Dspotless.apply.skip=true -Drat.skip=true clean package
情形二:需要使用存在 SPI 实现的 JAR 或 GPL V2 等 LICENSE 的第三方依赖的 JAR。
在 distribution/proxy-native/pom.xml 的 dependencies 加入存在 SPI 实现的 JAR
或第三方依赖的 JAR。示例如下
<dependencies>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.32</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-sql-translator-jooq-provider</artifactId>
<version>5.3.1</version>
</dependency>
</dependencies>
./mvnw -am -pl distribution/proxy-native -B -Pnative -DskipTests -Dmaven.javadoc.skip=true -Dcheckstyle.skip=true -Dspotless.apply.skip=true -Drat.skip=true clean package
server.yaml 的 /conf 文件夹,
第三个参数为绑定端口的 Address,第四个参数为 Force Start,如果为 true 则保证 ShardingSphere Proxy Native 无论能否连接都能正常启动。
假设已存在文件夹./custom/conf,示例为./apache-shardingsphere-proxy-native 3307 ./custom/conf "0.0.0.0" false
./mvnw -am -pl distribution/proxy-native -B -Pnative,docker.native -DskipTests -Dmaven.javadoc.skip=true -Dcheckstyle.skip=true -Dspotless.apply.skip=true -Drat.skip=true clean package
server.yaml 的 conf 文件夹为 ./custom/conf,可通过如下的 docker-compose.yml 文件启动 GraalVM Native
Image 对应的 Docker Image。version: "3.8"
services:
apache-shardingsphere-proxy-native:
image: apache/shardingsphere-proxy-native:latest
volumes:
- ./custom/conf:/opt/shardingsphere-proxy-native/conf
ports:
- "3307:3307"
oraclelinux:9-slim 作为 Base Docker Image。
但如果你希望使用 busybox:glic,gcr.io/distroless/base 或 scratch 等更小体积的 Docker Image 作为 Base Docker
Image,你需要根据 https://www.graalvm.org/22.3/reference-manual/native-image/guides/build-static-executables/ 的要求,
做为 pom.xml的 native profile 添加 -H:+StaticExecutableWithDynamicLibC 的 jvmArgs 等操作。
另请注意,某些第三方依赖将需要在 Dockerfile 安装更多系统库,例如 libdl。
因此请确保根据你的使用情况调整 distribution/proxy-native
下的 pom.xml 和 Dockerfile 的内容。针对 GraalVM Native Image 形态的 ShardingSphere Proxy,其提供的可观察性的能力与 https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-proxy/observability/ 并不一致。
你可以使用 https://www.graalvm.org/22.3/tools/ 提供的一系列命令行工具或可视化工具观察 GraalVM Native Image 的内部行为,并根据其要求使用 VSCode 完成调试工作。 如果你正在使用 IntelliJ IDEA 并且希望调试生成的 GraalVM Native Image,你可以关注 https://blog.jetbrains.com/idea/2022/06/intellij-idea-2022-2-eap-5/#Experimental_GraalVM_Native_Debugger_for_Java 及其后继。如果你使用的不是 Linux,则无法对 GraalVM Native Image 进行 Debug,请关注尚未关闭的 https://github.com/oracle/graal/issues/5648 。
对于使用 ShardingSphere Agent 等 APM Java Agent 的情形, GraalVM 的 native-image 组件尚未完全支持在构建 Native
Image 时使用 javaagent,你需要关注尚未关闭的 https://github.com/oracle/graal/issues/1065。
以下部分采用 Apache SkyWalking Java Agent 作为示例,可用于跟踪 GraalVM 社区的对应 issue。
下载 https://dlcdn.apache.org/skywalking/java-agent/8.12.0/apache-skywalking-java-agent-8.12.0.tgz ,
并解压到 ShardingSphere Git Source 的 distribution/proxy-native。
修改 distribution/proxy-native/pom.xml 的 native profile,
为 org.graalvm.buildtools:native-maven-plugin 的 configuration 添加如下的 jvmArgs。
<jvmArgs>
<arg>-Dskywalking.agent.service_name="your service name"</arg>
<arg>-Dskywalking.collector.backend_service="your skywalking oap ip and port"</arg>
<arg>-javaagent:./skywalking-agent/skywalking-agent.jar</arg>
</jvmArgs>
./mvnw -am -pl distribution/proxy-native -B -Pnative -DskipTests -Dmaven.javadoc.skip=true -Dcheckstyle.skip=true -Dspotless.apply.skip=true -Drat.skip=true clean package
