Config
特徵
- 1 動態加載:根據需要動態加載多個資源文件。 go config 在後臺管理並監控配置文件,並自動更新到內存中
- 2 資源可插拔: 從任意數量的源中進行選擇以加載和合並配置。後臺資源源被抽象爲內部使用的標準格式,並通過編碼器進行解碼。源可以是環境變量,標誌,文件,etcd,k8s configmap等
- 3 可合併的配置:如果指定了多種配置,它們會合併到一個視圖中。
- 4 監控變化:可以選擇是否監控配置的指定值,熱重啓
- 5 安全恢復: 萬一配置加載錯誤或者由於未知原因而清除,可以指定回退值進行回退
Sources
Source 是資源加載來源,支持以下形式:
- cli 命令行
- consul
- env
- etcd
- file
- flag
- memory
也有一些社區支持的插件: - configmap - nread from k8s configmap
- grpc - read from grpc server
- runtimevar - read from Go Cloud Development Kit runtime variable
- url - read from URL
- vault - read from Vault server
ChangeSet
Source返回ChangeSet,是多個後端的單例內部抽象
// ChangeSet represents a set of changes from a source
type ChangeSet struct {
// Raw encoded config data
Data []byte
// MD5 checksum of the data
Checksum string
// Encoding format e.g json, yaml, toml, xml
Format string
// Source of the config e.g file, consul, etcd
Source string
// Time of loading or update
Timestamp time.Time
}
Encoder
Encoder 處理配置文件的編碼與解碼,支持:
- json
- yaml
- toml
- xml
- xml
- hcl
Config
// Config is an interface abstraction for dynamic configuration
type Config interface {
// provide the reader.Values interface
reader.Values
// Stop the config loader/watcher
Close() error
// Load config sources
Load(source ...source.Source) error
// Force a source changeset sync
Sync() error
// Watch a value for changes
Watch(path ...string) (Watcher, error)
}
示例
在項目中創建config目錄,加入文件conf.go 與 db.toml
db.toml
[myslq]
host = "127.0.0.3"
port = 3306
conf.go
package config
import (
"github.com/micro/go-micro/v2/config"
"github.com/micro/go-micro/v2/config/encoder/toml"
"github.com/micro/go-micro/v2/config/source"
"github.com/micro/go-micro/v2/config/source/file"
)
func init() {
enc := toml.NewEncoder()
// Load toml file with encoder
config.Load(
file.NewSource(
file.WithPath("/home/luslin/go/workspace/tools/micro-hello/config/db.toml"),
source.WithEncoder(enc),
),
)
}
main.go 中加入
import _ "micro-hello/config"
go func() {
for range time.Tick(time.Second) {
conf := config.Map()
fmt.Println(conf)
}
}()
在運行時更改db.toml 文件,就可以看到值的變化
Errors
error type:
type Error struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Code int32 `protobuf:"varint,2,opt,name=code,proto3" json:"code,omitempty"`
Detail string `protobuf:"bytes,3,opt,name=detail,proto3" json:"detail,omitempty"`
Status string `protobuf:"bytes,4,opt,name=status,proto3" json:"status,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
使用
handler/micro.go
// Call is a single request handler called via client.Call or the generated client code
func (e *Micro) Call(ctx context.Context, req *hello.Request, rsp *hello.Response) error {
log.Info("Received Micro.Call request")
rsp.Msg = "Hello " + req.Name
return errors.BadRequest("com.foo.service.hello.Call", "invalid field")
}
使用 micro web 或前面的mico-hello-cli 項目調用接口
func main() {
// New Service
service := micro.NewService(
micro.Name("com.foo.service.micro.clinet"),
micro.Version("latest"),
)
service.Init()
resp,err := hello.NewMicroService("com.foo.service.micro",service.Client()).Call(context.TODO(),&hello.Request{Name: "lin"})
if err != nil {
e := errors.Parse(err.Error())
fmt.Println(e)
os.Exit(1)
}
fmt.Println(resp.Msg)
}
結果:
{"id":"com.foo.service.hello.Call","code":400,"detail":"invalid field","status":"Bad Request"}
類別
- BadRequest
- Unauthorized
- Forbidden
- NotFound
- MethodNotAllowed
- Timeout
- Conflict
- InternalServerError
如果默認的這些不滿足要求,可以使用New創建
// New generates a custom error.
func New(id, detail string, code int32) error {
return &Error{
Id: id,
Code: code,
Detail: detail,
Status: http.StatusText(int(code)),
}
}