一些中间件 | 青训营笔记

220 阅读5分钟

这是我参与「第五届青训营」伴学笔记创作活动的第27

Viper

概述

viper是go一个强大的流行的配置解决方案的库。viper是spf13的另外一个重量级库。有大量项目都使用该库,比如hugo, docker等。 它基本上可以处理所有类型的配置需求和格式, viper支持功能:

  • 设置默认配置
  • 支持各种配置文件,如JSON,TOML, YAML, HCL, envfile和Java属性配置文件
  • 支持监听文件变化以及重新读取配置
  • 支持从环境变量读取配置
  • 支持从远程配置系统(etcd或Consul)读取配置,并能监听远程配置修改
  • 支持从命令行标志Flag读取配置,比如搭配cobra使用
  • 支持读取缓冲区数据

安装: go get github.com/spf13/viper

使用

获取viper实例

viper包默认提供了一个全局的Viper实例

func GetViper() *Viper 
func New() *Viper 
func NewWithOptions(opts ...Option) *Viper 
func Sub(key string) *Viper
  1. viper.GetViper()获取的为全局的Viper实例对象
  2. NewNewWithOptions提供了创建实例的方法
  3. Sub读取子配置项提供了一个新的实例Viper

默认配置

viper.SetDefault("ContentDir", "content") 
viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"})

读配置

配置文件app.yml

app: 
    name: viper-test 
    mode: dev 
db: 
    mysql: 
        url: "root:root@tcp(127.0.0.1:3306)/stock?charset=utf8mb4&parseTime=True&loc=Local" 
    redis: 
        host: 127.0.0.1 
        port: 6067 
        db: 0 
        passwd: 123456

初始化viper

func InitConfig() (*viper.Viper, error) { 
    v := viper.New() v.AddConfigPath(".")// 添加配置文件搜索路径,点号为当前目录 
    v.AddConfigPath("./configs") // 添加多个搜索目录 
    v.SetConfigType("yaml")// 如果配置文件没有后缀,可以不用配置 
    v.SetConfigName("app.yml") // 文件名,没有后缀 
    // v.SetConfigFile("configs/app.yml") // 读取配置文件 
    if err := v.ReadInConfig(); err == nil {
        log.Printf("use config file -> %s\n", v.ConfigFileUsed()) 
    } else { 
        return nil,err 
   } return v, nil 
}

监听配置变化

func (v *Viper) WatchConfig()
func (v *Viper) WatchRemoteConfig() error 
func (v *Viper) WatchRemoteConfigOnChannel() error

logrus

概述

GitHub访问地址:github.com/sirupsen/lo…

golang中,流行的日志框架包括logrus、zap、zerolog、seelog等。logrus是目前Github上star数量最多的日志库

特性:

  1. 完全兼容golang标准库日志模块:logrus拥有六种日志级别:debug、info、warn、error、fatal和panic,这是golang标准库日志模块的API的超集。如果您的项目使用标准库日志模块,完全可以以最低的代价迁移到logrus上。
  2. 可扩展的Hook机制:允许使用者通过hook的方式将日志分发到任意地方,如本地文件系统、标准输出、logstash、elasticsearch或者mq等,或者通过hook定义日志内容和格式等。
  3. 可选的日志输出格式:logrus内置了两种日志格式,JSONFormatter和TextFormatter,如果这两个格式不满足需求,可以自己动手实现接口Formatter,来定义自己的日志格式。
  4. Field机制:logrus鼓励通过Field机制进行精细化的、结构化的日志记录,而不是通过冗长的消息来记录日志。
  5. logrus是一个可插拔的、结构化的日志框架

缺点:

  1. 没有提供行号文件名的支持
  2. 输出到本地文件系统没有提供日志分割功能
  3. 官方没有提供输出到ELK等日志处理中心的功能

使用

logrus.Debug("Useful debugging information.") 
logrus.Info("Something noteworthy happened!") 
logrus.Warn("You should probably take a look at this.") 
logrus.Error("Something failed but I'm not quitting.") 
logrus.Fatal("Bye.") //log之后会调用os.Exit(1) 
logrus.Panic("I'm bailing.") //log之后会panic()

另外还有一个+f的版本,用起来和Printf一样,区别在于是否识别格式化输出

logrus.Fatal("%s ", v.Get("args.name")) //FATA[0000] %sxiaoming 
logrus.Fatalf("%s ", v.Get("args.name")) //FATA[0000] xiaoming

Kitex

namespace go hello

struct ReqBody {
    1: string name 
    2: i32 type 
    3: string email 
} 

struct Request {
    1: string data 
    2: string message 
    3: ReqBody reqBody 
} 

struct Msg {
    1: i64 status 
    2: i64 code 
    3: string msg 
} 

struct Response {
    1: Msg msg 
    2: string data 
} 

service HelloService {
    Response echo(1: Request req) 
    Response testHello4Get(1: Request req) 
    Response testHello4Post(1: Request req) 
}

生成代码

kitex  -module  "hz-kitex-examples"  -thrift frugal_tag  -service  helloserver  idl/hello.thrift

  • -module module_name:"hz-kitex-examples"

    • 该参数用于指定生成代码所属的 Go 模块,会影响生成代码里的 import path。
    • 如果当前目录是在当前的目录,那么可以不指定该参数;会使用GOPATH/src 开始的相对路径作为 import path 前缀。例如,在 $GOPATH/src/example.com/hello/world 下执行 kitex,那么 kitex_gen/example_package/example_package.go 在其他代码代码里的 import path 会是 example.com/hello/world/kitex_gen/example_package。
    • 如果当前目录不在 $GOPATH/src 下,那么必须指定该参数。
    • 如果指定了 -module 参数,那么 kitex 会从当前目录开始往上层搜索 go.mod 文件
      • 如果不存在 go.mod 文件,那么 kitex 会调用 go mod init 生成 go.mod;
      • 如果存在 go.mod 文件,那么 kitex 会检查 -module 的参数和 go.mod 里的模块名字是否一致,如果不一致则会报错退出;
      • 最后,go.mod 的位置及其模块名字会决定生成代码里的 import path
  • -service service_name:helloserver

    • 使用该选项时,kitex 会生成构建一个服务的脚手架代码,参数 service_name 给出启动时服务自身的名字,通常其值取决于使用 Kitex 框架时搭配的服务注册和服务发现功能 -use path
    • 在生成服务端代码(使用了 -service)时,可以用 -use 选项来让 kitex 不生成 kitex_gen 目录,而使用该选项给出的 import path。
  • -combine-service

    • 对于 thrift IDL,kitex 在生成服务端代码脚手架时,只会针对最后一个 service 生成相关的定义。如果你的 IDL 里定义了多个 service 定义并且希望在一个服务里同时提供这些 service 定义的能力时,可以使用 -combine-service 选项。
    • 该选项会生成一个合并了目标 IDL 文件中所有 service 方法的 CombineService,并将其用作 main 包里使用的 service 定义。注意这个模式下,被合并的 service 之间不能有冲突的方法名。
  • -protobuf value

    • 传递给 protoc 的参数。会拼接在 -go_out 的参数后面。可用的值参考 protoc 的帮助文档。
  • -thrift value

    • 传递给 thriftgo 的参数。会拼接在 -g go: 的参数后面。可用的值参考 thriftgo 的帮助文档。kitex 默认传递了 naming_style=golint,ignore_initialisms,gen_setter,gen_deep_equal,可以被覆盖。