## 讀取和設置環境變量
除了讀取文件和命令行傳遞參數外,環境變量是另一個向應用傳遞參數的方式。本文將簡單探討如何獲取和操作基本的環境變量,然后我們一起來看看如何結合第三方庫[https://github.com/kelseyhightower/envconfig](https://github.com/kelseyhightower/envconfig)(Star 1741)來使用。
我們將構建一個可以通過JSON或環境變量讀取配置的應用程序。下一章節將進一步探索其他替代格式,包括TOML和YAML。
### 實踐
1. 創建config.go:
```
package envvar
import (
"encoding/json"
"os"
"github.com/kelseyhightower/envconfig"
"github.com/pkg/errors"
)
// LoadConfig將從存儲在路徑中的json文件中選擇加載文件,
// 然后根據envconfig struct標記覆蓋這些值。
// envPrefix是我們為環境變量添加的前綴。
func LoadConfig(path, envPrefix string, config interface{}) error {
if path != "" {
err := LoadFile(path, config)
if err != nil {
return errors.Wrap(err, "error loading config from file")
}
}
// envconfig.Process根據環境變量填充指定的結構
err := envconfig.Process(envPrefix, config)
return errors.Wrap(err, "error loading config from env")
}
// LoadFile 解析一個json文件并填充到config中
func LoadFile(path string, config interface{}) error {
configFile, err := os.Open(path)
if err != nil {
return errors.Wrap(err, "failed to read config file")
}
defer configFile.Close()
decoder := json.NewDecoder(configFile)
if err = decoder.Decode(config); err != nil {
return errors.Wrap(err, "failed to decode config file")
}
return nil
}
```
2. 創建main.go:
```
package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"myConcurrency/chapter2/envvar"
)
// Config 將保存我們從json文件和環境變量中捕獲的配置
type Config struct {
Version string `json:"version" required:"true"`
IsSafe bool `json:"is_safe" default:"true"`
Secret string `json:"secret"`
}
func main() {
var err error
// 建立一個臨時json配置文件
tf, err := ioutil.TempFile("", "tmp")
if err != nil {
panic(err)
}
defer tf.Close()
defer os.Remove(tf.Name())
// json 配置文件的內容
secrets := `{
"secret": "so so secret"
}`
if _, err = tf.Write(bytes.NewBufferString(secrets).Bytes()); err != nil {
panic(err)
}
// 向環境變量中添加變量及對應值
if err = os.Setenv("EXAMPLE_VERSION", "1.0.0"); err != nil {
panic(err)
}
if err = os.Setenv("EXAMPLE_ISSAFE", "false"); err != nil {
panic(err)
}
c := Config{}
// 從文件中讀取配置參數
if err = envvar.LoadConfig(tf.Name(), "EXAMPLE", &c); err != nil {
panic(err)
}
fmt.Println("secrets file contains =", secrets)
// 獲取環境變量參數及對應值
fmt.Println("EXAMPLE_VERSION =", os.Getenv("EXAMPLE_VERSION"))
fmt.Println("EXAMPLE_ISSAFE =", os.Getenv("EXAMPLE_ISSAFE"))
// c既保存了json配置文件的參數也保存了環境變量的參數 我們將其打印
fmt.Printf("Final Config: %#v\n", c)
}
```
3. 運行main.go,這會輸出:
```
secrets file contains = {
"secret": "so so secret"
}
EXAMPLE_VERSION = 1.0.0
EXAMPLE_ISSAFE = false
Final Config: main.Config{Version:"1.0.0", IsSafe:false,
Secret:"so so secret"}
```
### 說明
使用os包可以很容易的設置和讀取環境變量。第三方庫envconfig使用結構體tag將環境變量映射給結構體的方式很巧妙,有興趣可以閱讀其源碼。
LoadConfig函數可以從各種來源獲取配置信息,而不會產生大量開銷或太多額外的依賴關系值得借鑒。
另外,請注意錯誤的處理。在此章節中使用errors.Wrap來生成錯誤,以便我們可以在不丟失原始錯誤信息的情況下注釋錯誤。有關詳細信息,請參閱第4章“錯誤處理“。
* * * *
學識淺薄,錯誤在所難免。歡迎在群中就本書提出修改意見,以饗后來者,長風拜謝。
Golang中國(211938256)
beego實戰(258969317)
Go實踐(386056972)
- 前言
- 第一章 I/O和文件系統
- 常見 I/O 接口
- 使用bytes和strings包
- 操作文件夾和文件
- 使用CSV格式化數據
- 操作臨時文件
- 使用 text/template和HTML/templates包
- 第二章 命令行工具
- 解析命令行flag標識
- 解析命令行參數
- 讀取和設置環境變量
- 操作TOML,YAML和JSON配置文件
- 操做Unix系統下的pipe管道
- 處理信號量
- ANSI命令行著色
- 第三章 數據類型轉換和解析
- 數據類型和接口轉換
- 使用math包和math/big包處理數字類型
- 貨幣轉換和float64注意事項
- 使用指針和SQL Null類型進行編碼和解碼
- 對Go數據編碼和解碼
- Go中的結構體標簽和反射
- 通過閉包實現集合操作
- 第四章 錯誤處理
- 錯誤接口
- 使用第三方errors包
- 使用log包記錄錯誤
- 結構化日志記錄
- 使用context包進行日志記錄
- 使用包級全局變量
- 處理恐慌
- 第五章 數據存儲
- 使用database/sql包操作MySQL
- 執行數據庫事務接口
- SQL的連接池速率限制和超時
- 操作Redis
- 操作MongoDB
- 創建存儲接口以實現數據可移植性
- 第六章 Web客戶端和APIs
- 使用http.Client
- 調用REST API
- 并發操作客戶端請求
- 使用OAuth2
- 實現OAuth2令牌存儲接口
- 封裝http請求客戶端
- 理解GRPC的使用
- 第七章 網絡服務
- 處理Web請求
- 使用閉包進行狀態處理
- 請求參數驗證
- 內容渲染
- 使用中間件
- 構建反向代理
- 將GRPC導出為JSON API
- 第八章 測試
- 使用標準庫進行模擬
- 使用Mockgen包
- 使用表驅動測試
- 使用第三方測試工具
- 模糊測試
- 行為驅動測試
- 第九章 并發和并行
- 第十章 分布式系統
- 第十一章 響應式編程和數據流
- 第十二章 無服務器編程
- 第十三章 性能改進