在中大型公司,由于对Trino源码的定制魔改量越来越大,会随着时间推移而增大出现冷门bug的概率,所以需要建立一套自动测试机制,在魔改源码合入主分支时可以自动触发test case,通过特定单测的执行失败,来更清晰的判断是否过去的魔改涉及到了不符合社区源码原本假设的部分,并对魔改后的情况不一致进行修正。
Gitlab Runner正好可以提供这样的机制,提升更早发现源码改动问题的效率。
Gitlab Runner相当于Gitlab服务在另一个机器上的分布式slave节点,用于接收Gitlab主服务所在机器的任务并执行,并将执行结果汇报回Gitlab主服务节点。首先需要部署服务器在8核CPU、32G内存以上,并且看下已有Gitlab服务的版本,安装Runner的版本要尽量和主服务版本一致,以免出现冷门bug:
确定版本后,去主服务可网络连通的另一台机器上安装Gitlab Runner:
# 添加官方仓库
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
# 查看版本列表
yum list gitlab-runner --showduplicates | sort -r
# 安装指定版本
yum install gitlab-runner-12.6.0-1
# 安装完成后查看版本
gitlab-runner -v
安装和Gitlab主服务版本一致的Runner后,还需要反向注册回Gitlab主服务,让主服务知道它的存在,先看一下Gitlab主服务里Trino仓库中的Runner所需要信息,包括主服务的url以及registration token:
复制下来之后,在后续的Runner注册过程中贴到接下来的命令的输入中:
# 开始向Gitlab主服务注册自己
gitlab-runner register
# 在这里粘贴Gitlab主服务的url后回车
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
http://xxx.xxx.xxx.xxx:xxxx/
# 在这里粘贴前面看到的registration token后回车
Please enter the gitlab-ci token for this runner:
Bb1aWAr8Cn_HpN_y76o1
# 这里写一点描述并回车
Please enter the gitlab-ci description for this runner:
test服务器
# 这里给runner打标签并回车,可以控制是否只有带特定标签的Gitlab项目才能使用这个runner
Please enter the gitlab-ci tags for this runner (comma separated):
presto
# 指定以哪种方式启动runner的任务,shell即利用当前linux物理机环境起个进程,docker则每次启动一个容器
Please enter the executor: custom, parallels, ssh, virtualbox, kubernetes, docker, docker-ssh, shell, docker+machine, docker-ssh+machine:
shell
上述环节结束后,gitlab runner服务就会以gitlab-runner用户身份来启动,并且在Gitlab主服务界面也可以看到了,如下图所示:
刚启动时圆形灯是绿色的,我这里灰色是因为正在执行任务(连不上的时候也会显示灰色)。
上述部分更详细的教程可参考:
CI/CD 系列 | 一文让你掌握 Gitlab Runner - 掘金文本讲述了 Gitlab Runner 的设计结构,描述了Executor 的类型与选择方案,以及它的安装,注册,配置流程。https://juejin.cn/post/7134644436192985095一键安装gitlab runner - 简书概述 GitLab Runner是一个开源项目,用于运行作业并将结果发送到GitLab。GitLab Runner是Go编写,可以在Linux、Windows以及Mac OS...https://www.jianshu.com/p/0aa64d6b4638
默认参数配置在执行CICD任务的时候可能会遇到一些坑,所以针对Trino还是要修改一部分,首先修改gitlab-runner的配置文件:
vim /etc/gitlab-runner/config.toml
#以下为配置文件中的内容
concurrent = 1
check_interval = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "test服务器"
url = "http://xxx.xxx.xxx.xxx:xxxx/"
token = "xxxxx"
executor = "shell"
# 出于磁盘空间考虑可以把Gitlab主服务传来的project代码放在其他位置
builds_dir = "/data/app/gitlab-runner/"
# 单位为KB,Trino日志量很大,默认1M限制超出就直接失败,可以适当调大到50M以上
output_limit = 1024000
[runners.custom_build_dir]
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]
在部分目录下需要root用户权限的话,也可以修改一下systemd中相关配置:
vim /etc/systemd/system/gitlab-runner.service
# 以下为配置内容
[Unit]
Description=GitLab Runner
After=syslog.target network.target
ConditionFileIsExecutable=/usr/lib/gitlab-runner/gitlab-runner
[Service]
StartLimitInterval=5
StartLimitBurst=10
ExecStart=/usr/lib/gitlab-runner/gitlab-runner "run" "--working-directory" "/home/gitlab-runner" "--config" "/etc/gitlab-runner/config.toml" "--service" "gitlab-runner" "--syslog" "--user" "root"
# 在上面这里更换--user参数
Restart=always
RestartSec=120
[Install]
WantedBy=multi-user.target
修改之后生效配置,重新启动一下gitlab-runner服务:
systemctl daemon-reload
systemctl restart gitlab-runner
接着还需要去Gitlab网页端修改一下关于该runner的一些配置,如下图所示:
Trino源码的部分单测会自动通过docker下载一些其他组件服务的容器下来进行联合测试,所以还需要安装一下docker,详细步骤可以参考:
centos7安装Docker详细步骤(无坑版教程) - 腾讯云开发者社区-腾讯云在安装 Docker 之前,先说一下配置,我这里是Centos7 Linux 内核:官方建议 3.10 以上,3.8以上貌似也可。https://cloud.tencent.com/developer/article/1701451这里需要注意的是,安装好的docker默认镜像仓库是国外中央仓库,下载速度很慢,容易导致Trino单测过久超时失败,所以要修改一下国内镜像源:
vim /etc/docker/daemon.json
# 以下为配置内容
{
"registry-mirrors": [
"https://dockerproxy.com",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://ccr.ccs.tencentyun.com"
],
"data-root": "/data/docker"
}
保存后刷新配置并重启docker服务:
systemctl daemon-reload
service docker restart
这样前置环境就基本准备好了。
Gitlab可以自动识别项目根目录下的.gitlab-ci.yml配置文件,所以源码project中加入该文件push上去,并且Gitlab网页里开一个merge request即可自动触发:
stages:
- test
variables:
TESTCONTAINERS_PULL_PAUSE_TIMEOUT: 1800
TEST_REPORT_RETENTION_DAYS: 5
test:
stage: test
only:
- merge_requests
script:
- export JAVA_HOME=/usr/java/zulu17.36.17-ca-jdk17.0.4.1-linux_x64
- export PATH=$JAVA_HOME/bin:$PATH
- export MAVEN_OPTS="$MAVEN_OPTS -XX:+CrashOnOutOfMemoryError -Dmaven.wagon.rto=180000 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/tmp/gitlab-runner/dump/mvn.hprof"
- ./mvnw -pl '!:trino-docs,!:trino-server-rpm' clean install -DskipTests
- ./mvnw -pl '!:trino-accumulo,!:trino-atop,!:trino-bigquery,!:trino-cassandra,!:trino-clickhouse,!:trino-delta-lake,!:trino-docs,!:trino-server,!:trino-server-rpm,!:trino-druid,!:trino-elasticsearch,!:trino-geospatial,!:trino-google-sheets,!:trino-faulttolerant-tests,!:trino-hudi,!:trino-thrift,!:trino-memory,!:trino-kafka,!:trino-kinesis,!:trino-mariadb,!:trino-ml,!:trino-mongodb,!:trino-mysql,!:trino-oracle,!:trino-password-authenticators,!:trino-phoenix5,!:trino-pinot,!:trino-postgresql,!:trino-prometheus,!:trino-raptor-legacy,!:trino-redis,!:trino-redshift,!:trino-singlestore,!:trino-sqlserver,!:trino-teradata-functions,!:trino-test-jdbc-compatibility-old-server,!:trino-tpcds,!:trino-tpch' -DreuseForks=false -Dsurefire.exitTimeout=1800 -Dsurefire.useSystemClassLoader=false -Djdk.net.URLClassPath.disableClassPathURLCheck=true -Djdk.attach.allowAttachSelf -Djava.io.tmpdir=/data/tmp/gitlab-runner --fail-at-end -e -B -Dmaven.source.skip=true -Dair.check.skip-all verify
timeout: 1d
上述配置也可以参考Trino源码中的.github/workflows/ci.yml文件来编写,可以参考-pl参数的写法酌情跳过一些不太需要的maven模块。
通过merge request触发Gitlab CICD pipeline任务后,就可以在如下界面里看到单测执行历史,可以点进去查看或下载Gitlab Runner执行时返回的日志信息:
可以ctrl+f搜索日志中“test failure”的字样来查看单测失败的报错,针对报错再修改源码修复就行。
由于该单测跑一轮花费的时间很长,消耗机器资源较大,而且中间可能会有docker下载慢等偶发因素导致执行到一半就挂了,所以可以酌情修改一下源码中的配置,例如pom.xml里的测试堆大小,如果观察到GC慢等问题的话:
还可以酌情选择在有单测报错时不直接结束任务,而是继续执行下去,或者跳过一些自身场景不太需要的单测类,如下所示:
在中间出现单测任务资源扛不住挂了的问题,也可以参考:
java - The forked VM terminated without saying properly goodbye. VM crash or System.exit called - Stack Overflowhttps://stackoverflow.com/questions/23260057/the-forked-vm-terminated-without-saying-properly-goodbye-vm-crash-or-system-exi?page=1&tab=modifieddesc#tab-top