使用Jenkins进行构建推广时应该在哪里保存应用程序属性文件

47次阅读
没有评论

问题描述

正在使用Spring Boot开发Java后端服务。application.properties文件中包含数据库配置。用户在4个不同的环境(开发、测试、UAT和生产)中进行部署。不同环境的属性文件将不同。用户想知道应该将这些文件保存在哪里,并且如何使用Jenkins进行构建推广。用户正在使用Apache Tomcat来部署WAR文件。目前,用户将属性文件保存在C:\Program Files\Apache Software Foundation\Tomcat 7.0\conf目录中,并使用以下代码进行访问。

@PropertySource(value = {"file:${catalina.base}/conf/application_dev.properties"})

每次在不同环境中部署时,用户需要替换相应的文件名application_test/uat/production.properties,提交代码,然后让Jenkins进行构建和部署。现在用户还需要在不同环境中手动保存文件。请建议应该如何处理。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

根据12因素应用程序方法,应将配置文件保留在代码仓库之外。这样可以避免每次更改密码或小设置时都需要提交和重新构建流水线的麻烦。
以下是一种常见的做法:
1. 在代码仓库之外,为每个环境创建一个文件夹,其中包含具有相同名称的文件:

conf/dev/application.properties
conf/test/application.properties
conf/uat/application.properties
conf/prod/application.properties
  1. @PropertySource参数化,使用一个环境变量(如env):
@PropertySource("file:${catalina.base}/conf/${env}/application.properties")
  1. 确保在每个环境中定义一个操作系统环境变量,名称为env,并设置正确的值(例如dev、test、uat或prod)。根据你的应用程序启动方式(Linux上的J2EE服务器启动脚本?Spring Boot Docker容器?),设置环境变量不应该是一个问题。
  2. 你还可以从类路径加载文件,例如:
@PropertySource("classpath:${env}/application.properties")

如果你使用Maven构建项目,可以在src/main/resources下创建相应的文件夹,并将其复制到类路径中。
这样简化了很多事情。Jenkins不需要做任何额外的工作,因为相同的构建/发布产物可以在任何环境中运行。让Jenkins在重新配置应用程序以适应特定环境时通常是一个反模式。相反,你应该努力使单个Jenkins发布作业构建一个可以简单地在不同环境之间复制的构建产物。
这种方法有一个缺点。如果要创建新的环境,你需要向源代码控制添加一个新文件并创建一个新的构建产物。对于传统技术而言,设置新环境是很多工作(例如,配置VM和数据库),因此在代码中添加文件的“额外步骤”似乎不是一个问题。
对于更现代的云原生技术(如Kubernetes),你可以在几秒钟内按需设置环境。在这种情况下,你不希望在代码库中预先指定环境。相反,你应该遵循12factor.net方法,将每个属性定义为环境变量,并直接在Spring中使用它们。如果查看当前的Spring Boot文档,它默认使用环境变量。这意味着如果你没有定义@PropertySource,但使用了类似以下的代码:

@Value("${name}")
private String name;

它们将从同名的环境变量中设置(使用全大写)。然后,问题转移到“如何确保每个环境变量在每个环境中正确设置”。可以轻松设置环境变量的技术(如Kubernetes)通常也很容易管理环境变量。在Kubernetes中,你可以创建一个“ConfigMap”(例如“my-app-properties”),并将其作为环境变量挂载,其中每个键+值为应用程序定义一个唯一的环境变量。每个逻辑环境可以是一个单独的Kubernetes命名空间(可能在共享集群上用于开发/测试,但在生产中使用专用集群),该命名空间具有其自己的“my-app-properties”配置对象,用于定义该逻辑环境的环境变量。
你可以将这些设置放在源代码控制中,但不要放在应用程序源代码仓库中。相反,你可以采用“基础设施即代码”的方法,其中运行应用程序的所有内容(例如,所有设置环境的脚本和yaml)都在其自己的独立git仓库中。然后,你可以设置一个配置部署作业,该作业由配置仓库上的git webhook触发。这可以推送新的环境变量。这样可以实现配置更改的持续部署,这与应用程序代码的持续部署是独立的。
如果你使用Kubernetes,那么Helmfile是一个非常好的选择,因为它不会在git中没有更改的情况下更新任何Kubernetes配置。这意味着可以在每次推送到受保护的主分支时重新应用git仓库中的所有配置;helmfile将仔细检查已部署的内容,并仅更新需要更新的Kubernetes配置对象。

方案2

你可以为每个环境创建一个分支。例如,“dev”分支将构建和部署“dev”应用程序到“dev”环境。根据12因素,你应该将环境设置放在应用程序仓库之外。但有时,这样做比违反规则更费力。

正文完