go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时])


本节看看kratos的配置中心paladin(骑士)。

kratos对配置文件进行了梳理,配置管理模块化,如redis有redis的单独配置文件、bm有bm的单独配置文件,及为方便易用。

paladin 本质是一个config SDK客户端,包括了remote、file、mock几个抽象功能,方便使用本地文件或者远程配置中心,并且集成了对象自动reload功能。

现在看看paladin的几种配置方式 :

静态配置

照常 new 一个demo项目.

kratos new paladin

随便找个配置,看目录结构都知道http.toml在configs下,可以直接用名字get到,应该是kratos工具做了封装。

http.toml

[Server]
addr = "0.0.0.0:8000"
timeout = "1s"
// New new a bm server.
func New(s pb.DemoServer) (engine *bm.Engine, err error) {
var (
cfg bm.ServerConfig
ct paladin.TOML
)
if err = paladin.Get("http.toml").Unmarshal(&ct); err != nil {
return
}
if err = ct.Get("Server").UnmarshalTOML(&cfg); err != nil {
return
}

Get() 取到的是个Value结构,利用了encoding包(encoding包定义了供其它包使用的可以将数据在字节水平和文本表示之间转换的接口)做抽象接口。

// Value is config value, maybe a json/toml/ini/string file.
type Value struct {
val interface{}
slice interface{}
raw string
} // Unmarshal is the interface implemented by an object that can unmarshal a textual representation of itself.
func (v *Value) Unmarshal(un encoding.TextUnmarshaler) error {
text, err := v.Raw()
if err != nil {
return err
}
return un.UnmarshalText([]byte(text))
} // UnmarshalTOML unmarhsal toml to struct.
func (v *Value) UnmarshalTOML(dst interface{}) error {
text, err := v.Raw()
if err != nil {
return err
}
return toml.Unmarshal([]byte(text), dst)
}

直接kratos run的话,默认是读取的configs下的本地文件。 kratos/tool/run.go 里面是可以找到的.

package main

import (
"os"
"os/exec"
"path"
"path/filepath" "github.com/urfave/cli"
) func runAction(c *cli.Context) error {
base, err := os.Getwd()
if err != nil {
panic(err)
}
dir := buildDir(base, "cmd", 5)
conf := path.Join(filepath.Dir(dir), "configs")
args := append([]string{"run", "main.go", "-conf", conf}, c.Args()...)
cmd := exec.Command("go", args...)
cmd.Dir = dir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
panic(err)
}
return nil
}

flag注入

如果我们进行了build

I:\VSProject\kratos-note\paladin\paladin>cd cmd

I:\VSProject\kratos-note\paladin\paladin\cmd>kratos build
directory: I:\VSProject\kratos-note\paladin\paladin/cmd
kratos: 0.3.1
build success. I:\VSProject\kratos-note\paladin\paladin\cmd>cmd.exe
INFO 12/30-22:25:07.054 I:/VSProject/kratos-note/paladin/paladin/cmd/main.go:19 paladin start
panic: lack of remote config center args goroutine 1 [running]:
github.com/bilibili/kratos/pkg/conf/paladin.Init(0x0, 0x0, 0x0, 0x0, 0x0)
I:/VSProject/go/pkg/mod/github.com/bilibili/kratos@v0.3.2-0.20191224125553-6e1180f53a8e/pkg/conf/paladin/default.go:32 +0x25f
main.main()
I:/VSProject/kratos-note/paladin/paladin/cmd/main.go:20 +0x103 I:\VSProject\kratos-note\paladin\paladin\cmd>

会发现直接运行时跑不起来的,因为这时候找不到配置文件,因为这时候我们没有调用kratos run,paladin找不到配置目录。

实际paladin里面会有一个confPath变量,主函数做paladin.init()的时候会做flag注入。也方便了开发环境开发人员自行做配置修改。

package paladin

import (
"context"
"errors"
"flag"
) var (
// DefaultClient default client.
DefaultClient Client
confPath string
) func init() {
flag.StringVar(&confPath, "conf", "", "default config path")
} // Init init config client.
// If confPath is set, it inits file client by default
// Otherwise we could pass args to init remote client
// args[0]: driver name, string type
func Init(args ...interface{}) (err error) {
if confPath != "" {
DefaultClient, err = NewFile(confPath)
} else {
var (
driver Driver
) ......
I:\VSProject\kratos-note\paladin\paladin\cmd>cmd.exe -conf=I:\VSProject\kratos-note\paladin\paladin\configs
INFO 12/30-22:41:43.717 I:/VSProject/kratos-note/paladin/paladin/cmd/main.go:19 paladin start
2019/12/30 22:41:43 start watch filepath: I:\VSProject\kratos-note\paladin\paladin\configs
INFO 12/30-22:41:43.781 I:/VSProject/go/pkg/mod/github.com/bilibili/kratos@v0.3.2-0.20191224125553-6e1180f53a8e/pkg/net/http/blademaster/server.go:98 blademaster: start http listen addr: 0.0.0.0:8000
[warden] config is Deprecated, argument will be ignored. please use -grpc flag or GRPC env to configure warden server.
INFO 12/30-22:41:43.790 I:/VSProject/go/pkg/mod/github.com/bilibili/kratos@v0.3.2-0.20191224125553-6e1180f53a8e/pkg/net/rpc/warden/server.go:329 warden: start grpc listen addr: [::]:9000

在线热加载配置

在线读取、变更的配置信息,比如某个业务开关,实现配置reload实时更新。

// Map is config map, key(filename) -> value(file).
type Map struct {
values atomic.Value
}

paladin.Map 通过 atomic.Value 自动热加载

# service.go
type Service struct {
ac *paladin.Map
} func New() *Service {
// paladin.Map 通过atomic.Value支持自动热加载
var ac = new(paladin.TOML)
if err := paladin.Watch("application.toml", ac); err != nil {
panic(err)
}
s := &Service{
ac: ac,
}
return s
} func (s *Service) Test() {
sw, err := s.ac.Get("switch").Bool()
if err != nil {
// TODO
} // or use default value
sw := paladin.Bool(s.ac.Get("switch"), false)
}

测试

测试一下自动热加载,可以看到demo里面已经有添加了application.toml的自动热加载了

 if err := paladin.Watch("application.toml", ac); err != nil {
panic(err)
}

关于watch

可以看到watch里面有个协程在监视变动情况。


// Watch watch on a key. The configuration implements the setter interface, which is invoked when the configuration changes.
func Watch(key string, s Setter) error {
v := DefaultClient.Get(key)
str, err := v.Raw()
if err != nil {
return err
}
if err := s.Set(str); err != nil {
return err
}
go func() {
for event := range WatchEvent(context.Background(), key) {
s.Set(event.Value)
}
}()
return nil
}

我们写个get()接口,打印下app.toml的keys() 看看是否会热加载。

func (s *Service) Get(ctx context.Context, req *pb.Req) (reply *pb.Resp, err error) {

	log.Info("app toml : (%v)", s.ac.Keys())

app.toml

# This is a TOML document. Boom~
demoExpire = "24h" [app]
addr = ["127.0.0.1:9001", "127.0.0.1:9002", "127.0.0.1:9003"]

接着随便加个字段,再次调用get()可以看ttt到加了进来

# This is a TOML document. Boom~
demoExpire = "24h" [app]
addr = ["127.0.0.1:9001", "127.0.0.1:9002", "127.0.0.1:9003"] [ttt]
xixi = "haha"

远程配置中心

通过环境变量注入,例如:APP_ID/DEPLOY_ENV/ZONE/HOSTNAME,然后通过paladin实现远程配置中心SDK进行配合使用。

目前只可以看到这个步骤是在Init()的时候做的,paladin本质是个客户端包,在不知道服务端实现的情况下暂时没找到样例,有机会遇见再补上。

// Init init config client.
// If confPath is set, it inits file client by default
// Otherwise we could pass args to init remote client
// args[0]: driver name, string type
func Init(args ...interface{}) (err error) {
if confPath != "" {
DefaultClient, err = NewFile(confPath)
} else {
var (
driver Driver
)
argsLackErr := errors.New("lack of remote config center args")
if len(args) == 0 {
panic(argsLackErr.Error())
}
argsInvalidErr := errors.New("invalid remote config center args")
driverName, ok := args[0].(string)
if !ok {
panic(argsInvalidErr.Error())
}
driver, err = GetDriver(driverName)
if err != nil {
return
}
DefaultClient, err = driver.New()
}
if err != nil {
return
}
return
}

体感paladin使用舒适度还是挺不错的、

断剑重铸之日,骑士归来之时

go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时])的更多相关文章

  1. 《深入理解Spring Cloud与微服务构建》学习笔记(二十)~配置中心Spring Cloud Config

    本例重新创建项目,构建一个空的mavan工程. 一.Config Server 从本地读取配置文件 新建一个moudle config_server ,pom添加依赖   <dependency ...

  2. # go微服务框架kratos学习笔记六(kratos 服务发现 discovery)

    目录 go微服务框架kratos学习笔记六(kratos 服务发现 discovery) http api register 服务注册 fetch 获取实例 fetchs 批量获取实例 polls 批 ...

  3. go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer)

    目录 go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer) demo demo server demo client 池 dao service p2c ro ...

  4. go微服务框架kratos学习笔记四(kratos warden-quickstart warden-direct方式client调用)

    目录 go微服务框架kratos学习笔记四(kratos warden-quickstart warden-direct方式client调用) warden direct demo-server gr ...

  5. go微服务框架kratos学习笔记八 (kratos的依赖注入)

    目录 go微服务框架kratos学习笔记八(kratos的依赖注入) 什么是依赖注入 google wire kratos中的wire Providers injector(注入器) Binding ...

  6. go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin)

    目录 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin) zipkin使用demo 数据持久化 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin ...

  7. 微服务框架surging学习之路——序列化 (转载https://www.cnblogs.com/alangur/p/10407727.html)

    微服务框架surging学习之路——序列化   1.对微服务的理解 之前看到在群里的朋友门都在讨论微服务,看到他们的讨论,我也有了一些自己的理解,所谓微服务就是系统里的每个服务都 可以自由组合.自由组 ...

  8. golang微服务框架go-micro 入门笔记2.4 go-micro service解读

    本章节阐述go-micro 服务发现原理 go-micro架构 下图来自go-micro官方 阅读本文前你可能需要进行如下知识储备 golang分布式微服务框架go-micro 入门笔记1:搭建go- ...

  9. golang微服务框架go-micro 入门笔记2.3 micro工具之消息接收和发布

    本章节阐述micro消息订阅和发布相关内容 阅读本文前你可能需要进行如下知识储备 golang分布式微服务框架go-micro 入门笔记1:搭建go-micro环境, golang微服务框架go-mi ...

随机推荐

  1. 【Linux】vim缩进配置 (转载)

    1.安装vim,终端输入: wanpeng@ubuntu:~$ sudo apt-get install vim-full 2.终端输入,打开配置文件: wanpeng@ubuntu:~$ vim ~ ...

  2. php-textarea 换行

    PHP接收表单提交的信息之后 存入数据库 再次从数据库获取数据再前端显示时  空格还有回车都消失了: 解决办法: 1,存入数据库时候进行替换 2,或者在取出数据之后进行替换 然后再在html中显示 s ...

  3. css3 练习

    css3 文本效果 css3中包含几个新的文本特征 在本章中您将了解一下文本属性 text-shadow box-shadow word-wrap word-break css3 的文本阴影 css3 ...

  4. P2P四红线

    P2P四红线 刘张君指出,P2P网络借贷平台是一种新兴金融业态,在鼓励其创新发展的同时,要记住四点:一是要明确这个平台的中介性质,二是要明确平台本身不得提供担保,三是不得将归集资金搞资金池,四是不得非 ...

  5. php第三方登录(微博登录,仿照慕课网)

    https://www.cnblogs.com/haoyu521/p/5606931.html 1:开发之前,请大家先自行熟悉一下OAuth协议原理. 2:我们开发需要具备一个外网可访问的线上域名,如 ...

  6. hdu 1045 Fire Net(dfs)

    Fire Net Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  7. HDU 1698 Just a Hook 线段树区间更新、

    来谈谈自己对延迟标记(lazy标记)的理解吧. lazy标记的主要作用是尽可能的降低时间复杂度. 这样说吧. 如果你不用lazy标记,那么你对于一个区间更新的话是要对其所有的子区间都更新一次,但如果用 ...

  8. Hammersley-Clifford定理证明

    Proof of Hammersley-Clifford TheoremProof of Hammersley-Clifford Theorem依赖知识定义1定义2证明过程反向证明(吉布斯分布=> ...

  9. H3C 帧中继显示与调试(续)

  10. uni-app学习记录01-pages配置项

    { // 每个页面都需要在pages里面去声明配置 "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/coll ...