要求: 根据golang中的环境(例如QA,PROD)配置数据库连接。 例如:
{"QA":{
"host":"124.44.2.2",
"port":"1234"
},
"PROD":{
"host":"125.65.23.64",
"port":"1234"
}
}
我可以用JSON / YAML等配置它,但是问题是当我们构建go时,构建文件不包含非go文件。因此,将构建部署到不同的实例时,它将丢失配置文件。
另一个解决方案,我尝试在go本身中设置config(通过设置常量)。然后根据作为参数传递的环境名称读取常量。但是然后在docker中,参数是在构建文件名之后传递的,而在go中,它只有在构建文件名之前传递才能读取参数。
有人可以推荐最佳解决方案吗?
答案 0 :(得分:2)
您通常不会在构建时烘烤运行时环境的配置。您需要一个通用的且独立于部署环境的构建二进制文件(或Docker映像或其他)。应该在运行时提供任何外部资源配置,以便在应用程序启动时晚绑定配置。
考虑可从Internet免费获得的第三方组件。它们以 generic 的方式编写,这使其不仅适用于您的环境,还适用于任何下载它们的人的环境。
这种方法要求您具有一种机制,用于将应用程序部署到开发,测试,生产或类似环境中时提供配置指令。
您可以使用多种机制来实现此目的。以下列表是非详尽:
在应用程序的顶级定义环境变量,并在生成应用程序二进制文件时将其传递给它们。例如,您可以定义环境变量DATABASE_HOSTADDR
并将其设置为等于所需数据库服务器的host:port
。使用您的main
方法或类似方法:
// Load database host address
dbHostAddr, ok := os.LookupEnv("DATABASE_HOSTADDR")
if !ok || dbHostAddr == "" {
log.Fatal("DATABASE_HOSTADDR not specified")
}
// Do something here to use the value retrieved from the env var,
// splitting on the port separator (:) if necessary to retrieve
// the hostname and port number as separate values.
您可能会使用一个库来解析二进制文件启动时提供的参数。因此,例如,如果您的应用程序名称为somebinary
,则可以使用:
./somebinary dbserver:12345
,或者,如果您使用命令行标志(由Go的内置flag
库提供,则为其他标志):
./somebinary --db dbserver:12345
使用标志的示例:
package main
import (
"flag"
"log"
)
var dbHostAddr string
func main() {
flag.Parse()
if dbHostAddr == "" {
log.Fatalf("--db flag must be specified")
}
// Do something with dbHostAddr
}
func init() {
// Bind desired flags
flag.StringVar(&dbHostAddr, "db", "", "Database connection path, in format host:port")
}
使用os.Args
的示例:
package main
import (
"log"
"os"
)
func main() {
if len(os.Args) < 2 {
log.Fatalf("database host address not supplied")
}
dbHostAddr := os.Args[1]
// Do something with dbHostAddr
}
Go中支持解析各种格式的配置文件,如果不包含,则有最受欢迎的库。如果您的配置要求更复杂,请考虑编写配置文件并将其与应用程序一起部署。
配置管理解决方案(例如Ansible或Salt)将在此处帮助您定义代码中的部署过程和基础结构配置,并有可能为您生成配置。如果您的配置是简单且静态的,则可以将其直接存储到源代码管理中,并在构建过程中将其打包为构建工件。