背景
在當前的微服務時代,每個服務通常獨立部署,並且可能有其自身的配置需求。應用程式配置檔案通常用於儲存設定和引數,以配置應用程式的操作方式。這些檔案與程式碼分離,使開發人員可以在不修改原始碼的情況下調整應用程式的行為。有幾種流行的配置檔案格式,包括 JSON、YAML、TOML、XML 和 INI。每種格式都有其優勢和適用場景。
YAML 檔案
YAML 是一種簡潔、易於人類書寫和閱讀的資料序列化語言,近年來迅速流行。其簡潔的語法讓它在配置檔案編寫中備受歡迎,尤其是在需要高度可讀性時。許多主流工具和平臺,如 AWS CloudFormation 模板、OpenAPI、Swagger 以及 Kubernetes,廣泛使用 YAML 來建立結構清晰、可讀性強的配置檔案,極大地提升了配置管理的效率和靈活性。
以下是 YAML 的規則簡要整理:
- 縮排規則: 使用空格表示層級,空格數量需一致,不能使用製表符。
- 鍵值對錶示: 鍵和值之間用冒號加空格分隔。
- 列表表示: 使用連字元加空格表示列表項。
-
布林值: 使用
true
/false
來表示布林型別,區分大小寫。 -
註釋: 使用
#
表示註釋。 - 字串表示: 字串無需加引號,特殊字元除外。
-
換行: 長文字可以透過換行符
|
或>
進行摺疊表示。 -
引用: 支援錨點(
&
)和別名(*
)進行引用,避免重複配置。
下面我們來請出今天的主角。
ymal.v3 基礎
gopkg.in/yaml.v3
是 Go 語言中用於解析和生成 YAML(YAML Ain't Markup Language)資料的一個非常流行的庫。它支援 YAML 1.2 版本,能夠提供完整的編碼和解碼功能,適用於處理結構化資料。
主要功能:
- YAML 解析與生成:支援從 YAML 檔案或資料流中讀取和寫入資料。
- 支援複雜資料結構:可以解析包括對映、列表、巢狀結構在內的各種複雜資料型別。
- 序列化和反序列化:可以將 Go 結構體轉為 YAML 檔案,或將 YAML 資料解析為 Go 結構體。
- 流處理:支援從輸入流中逐行解析資料,適合處理大型 YAML 檔案。
示例
下面是一個解析 YAML 資料的例子:
package main
import (
"fmt"
"gopkg.in/yaml.v3"
)
var data = `
name: FunTester
age: 30
languages:
- Go
- Java
- JavaScript
`
func main() {
var person map[string]interface{}
err := yaml.Unmarshal([]byte(data), &person)
if err != nil {
panic(err)
}
fmt.Printf("解析後的資料: %v\n", person)
}
控制檯輸出:
解析後的資料: map[age:30 languages:[Go Java JavaScript] name:Alice]
下面來一個生成 YAML 資料的演示:
package main
import (
"fmt"
"gopkg.in/yaml.v3"
)
func main() {
person := map[string]interface{}{
"name": "Bob",
"age": 25,
"languages": []string{"Go", "JavaScript"},
}
out, err := yaml.Marshal(&person)
if err != nil {
panic(err)
}
fmt.Printf("生成的 YAML 資料:\n%s", out)
}
控制檯輸出:
生成的 YAML 資料:
age: 25
languages:
- Go
- JavaScript
name: Bob
ymal.v3 進階
下面我們來研究一下進階用法中的結構體與 yaml
檔案轉換,主要是從 yaml
檔案讀取資料,轉成 Go
語言的結構體的過程,為了方便,我寫到一個檔案當中了。
下面是本地的 config.yaml
檔案內容:
dbConfig:
host: db-host
username: admin
password: admin_pwd
下面是我的測試程式碼:
package main
import (
"encoding/json"
"fmt"
"os"
"sigs.k8s.io/yaml")
func main() {
//讀取當前目錄下的檔案
file, err := os.ReadFile("config.yaml")
if err != nil {
panic(err)
}
//列印檔案內容
println(string(file))
defer func() {
if err := recover(); err != nil {
println(err)
}
}()
var o DbConfigRoot
yaml.Unmarshal(file, &o)
//把結構體轉成json
jsonData, _ := json.Marshal(o.DbConfig)
fmt.Println(string(jsonData))
}
type DbConfigRoot struct {
DbConfig DbConfig `yaml:"dbConfig"`
}
type DbConfig struct {
Host string `yaml:"host"`
UserName string `yaml:"username"`
Password string `yaml:"password"`
}
下面我們來看看控制檯列印的內容:
dbConfig:
host: db-host
username: admin
password: admin_pwd
port: 3306
{"Host":"db-host","UserName":"admin","Password":"admin_pwd"}
非常完美地實現了我們的預期。
誇誇
下面是 yaml.v3
的優點:
- 全面支援 YAML 1.2:提供完整的解析和生成功能,支援最新的 YAML 規範。
- 簡單易用:提供了直觀的 API,可以輕鬆將 YAML 資料和 Go 結構體進行相互轉換,簡化了配置檔案的解析和處理。
- 支援複雜資料結構:能夠處理巢狀的對映、列表、陣列等複雜資料型別,適應各種實際應用場景。
- 序列化與反序列化靈活:支援將 Go 結構體序列化為 YAML 檔案,也可以將 YAML 檔案內容解析為 Go 結構體或 map,非常適合配置管理和資料交換。
- 流處理支援:可以按流(如從檔案或網路接收的流式資料)解析 YAML,適合處理大型檔案或資料流的場景。
- 錯誤處理清晰:解析和生成過程中有明確的錯誤提示,方便除錯與排查問題。
- 跨版本相容性:使用 gopkg.in 版本管理,確保相容性,同時方便使用者根據需要選擇合適的版本。
gopkg.in/yaml.v3
是 Go 語言中處理 YAML 格式資料的強大工具,適用於解析和生成各種複雜的配置檔案。它不僅支援 YAML 1.2 規範,還提供了靈活的序列化和反序列化功能,幫助開發者輕鬆實現資料和結構體的轉換。其流式處理支援特別適合大規模資料解析場景,提升了處理效率。同時,清晰的錯誤提示和友好的 API 設計使得開發體驗更加順暢。無論是在微服務架構中載入配置檔案,還是在複雜系統中處理巢狀資料結構,gopkg.in/yaml.v3
都是一個不可或缺的工具。對於任何需要 YAML 解析或生成的應用場景,它都能以簡潔、高效的方式提供可靠的支援,是 Go 開發者值得信賴的選擇。
FunTester 原創精華
- 混沌工程、故障測試、Web 前端
- 服務端功能測試
- 效能測試專題
- Java、Groovy、Go
- 白盒、工具、爬蟲、UI 自動化
- 理論、感悟、影片