我们有少量用于集成测试的共享数据库以及共享这些数据库的大量分支。有没有办法阻止Bamboo同时尝试运行使用相同数据库的多个分支?
当多个分支中的构建并行运行时,它们会互相破坏并失败。
答案 0 :(得分:7)
此BAM-12071和BAM-2423等待Atlassian实施解决方案的优秀功能请求。
与此同时,我们基于使用旧式文件(实际上是目录)锁定为此设计了一个快速而又脏的解决方法。每个资源都在作业或分支配置中使用变量名gatekeeper.resource
定义。在构建过程开始时," Gatekeeper" stage使用公共服务器上的公共文件中的目录名检查所需资源是否空闲。目录名称存在时,资源正在使用中。后续构建阶段的第一个任务将资源名称创建为空目录,最终任务将其删除。其他构建无法继续第一阶段,直到资源空闲,停止并发构建。缺点是它确实占据了当地的竹子代理商,并不是完全万无一失,但99%的时间对我们有用。如果正确定义了资源变量,它甚至可以在构建计划中工作。
它被定义为针对linux实例的SSH任务:
# This Gatekeeper stage prevents concurrent builds against a resource
# by looking for a directory instance in a common file area.
# If the directory exists the build cannot proceed until it disappears.
# The build sleeps as long as the directory exists.
#
# The first task in the subsequent stage is to create the directory, and
# a final task in the build removes it.
# As a failsafe a background half-hourly cron job should remove lock
# dirs if they exceed 3 x the build time.
#########################################################
# Wait for a random number of seconds 20-120 to reduce (but not eliminate) the chance that multiple competing branch
# builds triggered by timers both see the dir gone and start the unit test job at once and then proceed to clobber each other (i.e a race condition)
# note: bamboo expects output every 3 minutes so do not increase beyond 180 seconds
SLEEPYTIME=$(( ( RANDOM % 100 ) + 20 ))
echo SLEEPYTIME today is $SLEEPYTIME
sleep $SLEEPYTIME
# Wait for the Gatekeeper lock dir to disappear... or be older than 3 hours (previous build may have hung)
file=/test/atlassian/bamboo-gatekeeper/inuse-${bamboo.gatekeeper.resource}
while [ -d "$file" ]
do
echo $(date +%H:%M:%S) waiting $SLEEPYTIME seconds...
sleep $SLEEPYTIME
done
exit 0
构建阶段的第一个工作任务(在关守之后):
# This will fail if the lock file (actually a directory!) already exists
file=/test/atlassian/bamboo-gatekeeper/inuse-${bamboo.gatekeeper.resource}
mkdir "$file"
构建之后构建阶段的最后一步(成功或其他)
file=/test/atlassian/bamboo-gatekeeper/inuse-${bamboo.gatekeeper.resource}
rm -rf "$file"
还有一个故障安全的cron清理任务,它删除了几个小时之前的所有资源网关目录(在我们的例子中为3)。不应该是必要的,但如果竹子本身重新启动而不执行最后的任务,则可以无限制地阻止构建。
# This works in conjunction with bamboo unit tests. It clears any unit test lock files after 3 hours (e.g. build has hung or killed without removing lock file)
15,45 * * * * find /test/atlassian/bamboo-gatekeeper -name inuse* -mmin +180 -delete
gatekeeper.resource
可以定义为您想要的任何名称。在我们的例子中,它是集成测试使用的数据库模式。我们的一些分支使用通用的测试环境,其他分支有自己的实例。此解决方案使用公共环境阻止分支同时执行,同时允许具有自己环境的分支继续执行。
将并发构建限制为特定数字并不是一个完整的解决方案,但在Atlassian实施永久解决方案之前,这足以让我们解决这个问题。我希望它能帮助别人。