Golang读取及使用环境变量
JSON
HTTPMySQL
SERVER_PORT=80 # HTTP服务端口
MYSQL_HOST=mysql.domain.local # MySQL主机地址
MYSQL_PORT=3306 # MySQL端口
MYSQL_USER=jack # MySQL用户名
MYSQL_PASSWD=Jk_220107 # MySQL密码
MYSQL_INSTANCE=test # MySQL数据库名
接下来通过代码与配置文件读取的异同。
读取系统环境变量
GoAPI
func Setenv(key, value string) error // 设置环境变量,失败时返回error
func Unsetenv(key string) error // 取消设置环境变量,失败时返回error
func Getenv(key string) string // 获取环境变量,不存在时返回空字符串
func LookupEnv(key string) (string, bool) // 查询环境变量,存在时bool返回true且string有值,否则为false且string为空
func ExpandEnv(s string) string // 替换字符串中的${var}或$var为当前的系统环境变量,不存在则替换为空
func Clearenv() // 清除环境变量
GetenvLookupEnv
package main
import (
"fmt"
"os"
"net/http"
)
// DSN: Data Source Name
func getDSN() string {
/* Getenv也或等价换成LookupEnv调用
dbHost := os.Getenv("MYSQL_HOST")
dbPort := os.Getenv("MYSQL_PORT")
dbUser := os.Getenv("MYSQL_USER")
dbPasswd := os.Getenv("MYSQL_PASSWD")
dbName := os.Getenv("MYSQL_INSTANCE")
if len(dbHost) != 0 && len(dbPort) != 0 && len(dbUser) != 0 && len(dbPasswd) != 0 && len(dbName) != 0 {
return fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", dbUser, dbPasswd, dbHost, dbPort, dbName)
}
*/
if dbHost, ok := os.LookupEnv("MYSQL_HOST"); ok {
if dbPort, ok := os.LookupEnv("MYSQL_PORT"); ok {
if dbUser, ok := os.LookupEnv("MYSQL_USER"); ok {
if dbPasswd, ok := os.LookupEnv("MYSQL_PASSWD"); ok {
if dbName, ok := os.LookupEnv("MYSQL_INSTANCE"); ok {
return fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", dbUser, dbPasswd, dbHost, dbPort, dbName)
}
}
}
}
}
return ""
}
func homeHandler(rw http.ResponseWriter, r *http.Request) {
fmt.Fprintf(rw, "Hello, world!")
}
func main() {
http.HandleFunc("/", homeHandler)
svrPort := osGetenv("SERVER_PORT")
if len(svrPort) != 0 {
http.ListenAndServe(":" + svrPort, nil)
}
}
由于环境变量散落在代码里,且无法动态修改或增减,通过配置文件加载可以更加灵活些。
通过JSON文件配置的环境变量
config.json
{
"server_port": ${SERVER_PORT},
"mysql_host": "${MYSQL_HOST}",
"mysql_port": ${MYSQL_PORT},
"mysql_user": "${MYSQL_USER}",
"mysql_passwd": "${MYSQL_PASSWD}",
"mysql_instance": "${MYSQL_INSTANCE}"
}
代码实现如下:
package main
import (
"fmt"
"os"
"net/http"
"io/ioutil"
"encoding/json"
)
type svrConfig struct {
ServerPort int `json:"server_port"`
MySQLHost string `json:"mysql_host"`
MySQLPort int `json:"mysql_host"`
MySQLUser string `json:"mysql_host"`
MySQLPasswd string `json:"mysql_host"`
MySQLInstance string `json:"mysql_instance"`
}
// DSN: Data Source Name
func getDSN(dbHost string, dbPort int, dbUser string, dbPasswd string, dbName string) string {
return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", dbUser, dbPasswd, dbHost, dbPort, dbName)
}
func homeHandler(rw http.ResponseWriter, r *http.Request) {
fmt.Fprintf(rw, "Hello, world!")
}
func main() {
cfg := svrConfig{}
if orgData, err := ioutil.ReadFile('config.json'); err != nil {
panic(err.Error())
} else {
data := os.ExpandEnv(string(orgData))
if err := json.Unmarshal([]byte(data), cfg); err != nil {
panic(err.Error())
}
// TODO: dsn for mysql connection
dsn := getDSN(cfg.MySQLHost, cfg.MySQLPort, cfg.MySQLUser, cfg.MySQLPasswd, cfg.MySQLInstance)
fmt.Fprintf("dsn: %s.", dsn)
http.HandleFunc("/", homeHandler)
http.ListenAndServe(":" + cfg.SeverPort, nil)
}
}
os.Getenvos.LookupEnvos.ExpandEnvos.ExpandEnvyaml
$var${var}${test:-abc}bash