提前声明:下文均使用Gradle进行项目的管理,没有使用Maven进行项目的管理。

1. 准备工作

注意:

  • 1.GraalVM编译需要gcc,在编译打包之前需要在Jenkins编译机器上先安装gcc。
  • 2.GraalVM编译需要libz.a,因此需要在Jenkins编译机器上先安装zlib
  • 3.GraalVM打包成为本地的二进制文件,因此它没有跨平台特性,如果想要在Linux上部署服务,就必须在Linux机器上进行打包
  • 4.GraalVM打包必须使用GraalVM专属的JDK进行编译,不能使用普通的JDK进行打包,可以从Oracle官网https://www.oracle.com/cn/java/technologies/downloads/#java24进行GraalVM的下载。

安装GCC:

sudo apt install gcc

安装zlib:

# ubuntu
sudo apt-get install zlib1g-dev
# centos
sudo yum install zlib-devel
# homebrew
brew install zlib

2.自定义GraalVM编译参数

Jenkins的编译Shell脚本如下,注意必须使用GraalVM的JDK进行编译和打包,使用普通的JDK无法进行GraalVM的编译打包。具体可以从Oracle官网https://www.oracle.com/cn/java/technologies/downloads/#java24上进行下载。

JAVA_HOME=/home/wanna/graalvm-jdk21
./gradlew clean nativeCompile -x test

对应的是Jenkins的BuildSteps这部分的配置。

image-cz6b.png

类型选择执行Shell。

image-mt8e.png

3.部署命令

编译之后,上传到目标机器上的启动脚本:

lsof -t -i:8080 | xargs -r kill -9 && cd /home/wanna/datasync/schedule-datasync/ && chmod a+x datasync-server && nohup ./datasync-server > info.log 2>&1 &

对应的是Jenkins中的"构建后操作"。

image-ivmo.png

注意:

    1. Source files决定我们要上传的文件列表,GraalVM的Gradle插件打包出来的产物放在build/native/nativeCompile/目录下,我们需要将build/native/nativeCompile/*上传到服务器上。
    1. 为了上传到远程服务器后,目录中的build/native/nativeCompile丢掉,在Remove prefix中,把这部分去掉,这样上传到目标服务器后目录就短一些。
    1. Remote directory中需要配置上传到服务器的哪个文件夹下,我这里填写的是schedule-datasync,代表我希望打包的二进制文件产物上传到这个文件夹下(注意Publish Over SSH插件本地配置了登录时的默认工作路径,两者路径拼接之后才是真正的目录)。

类型选择"Send build artifcats over SSH"(注意需要先安装"Publish Over SSH"插件)

image-xya4.png

4. 出现问题介绍

4.1 重复部署8080端口会出现端口冲突

使用如下的命令,找出来8080端口所占用的进程PID,使用kill命令进行杀掉。

lsof -t -i:8080 | xargs -r kill -9

4.2 上传的二进制文件没有x执行权限

解决方式:在部署命令中给二进制可执行文件先加上+x的权限再进行执行。

chmod a+x datasync-server

4.3 CPU指令集不兼容

出现问题详细如下:

The current machine does not support all of the following CPU features that are required by the image: [CX8, CMOV, FXSR, MMX, SSE, SSE2, SSE3, SSSE3, SSE4_1, SSE4_2, POPCNT, LZCNT, AVX, AVX2, BMI1, BMI2, FMA].
Please rebuild the executable with an appropriate setting of the -march option.

这种情况,说明GraalVM编译时,用到了一些高级的指令集,但是当前的CPU并不支持。

此时我们需要修改Gradle的配置,对GraalVMExtension进行配置,新增一个-march=x86-64参数,使用通过的x86-64结构,可以兼容大多数的服务器。

configure<GraalVMExtension> {
    binaries {
        named("main") {
            buildArgs.add("-march=x86-64")
        }
    }
}

修改后,重新进行提交代码,并触发Jenkins部署。当去服务器上看到如下的SpringBoot启动日志,说明启动成功(/home/wanna/datasync/schedule-datasync/datasync-server可以看到,用的是二进制的包进行的启动,而不是用的jar包进行的启动)。

2025-03-30T18:49:59.542Z  INFO 1845 --- [datasync-server] [           main] c.w.p.d.DatasyncServerApplicationKt      : Starting AOT-processed DatasyncServerApplicationKt using Java 21.0.6 with PID 1845 (/home/wanna/datasync/schedule-datasync/datasync-server started by wanna in /home/wanna/datasync/schedule-datasync)