Apollo配置中心
配置格式
service = "http://127.0.0.1:8080" # apollo配置服务地址
cache_dir = "/to/path" # 本地配置缓存
[app.sales-micro]
app_id = "sales-micro" # 服务端的应用id
cluster = "default" # 服务端集群
secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # 应用秘钥
namespaces = ["gateway:SALES.micro.gateway"] # 需要拉取的应用命名空间(配置项),格式为 "别名:命名空间"
[app.sales-micro-holdings]
app_id = "sales-micro-holdings"
cluster = "default"
secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
namespaces = [
"holdings.dst:SALES.micro.dispatcher",
"holdings.cb:SALES.micro.circuit_breaker",
"holdings.rl:SALES.micro.rate_limiter"
]
[app.sales-micro-paipaibao]
app_id = "sales-micro-paipaibao"
cluster = "default"
secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
namespaces = [
"paipaibao.dst:SALES.micro.dispatcher",
"paipaibao.cb:SALES.micro.circuit_breaker",
"paipaibao.rl:SALES.micro.rate_limiter"
]
启动
apConf := &pkg.ApolloConfPkg{}
if err := pkg.Config.Read("apollo").Unmarshal(apConf); err != nil {
panic(err)
}
err = pkg.Apollo.Start(apConf, func(appId string, namespace string, changeKeys []string) {})
......
调用
// viper方式读取配置
c := pkg.ApolloAlias("gateway")
allServices := c.GetStringSlice("all_services")
// 结构体方式读取配置
type SalesMicroGateway struct {
AllServices []string `mapstructure:"all_services"`
SigEnable bool `mapstructure:"sig.enable"`
}
c := &SalesMicroGateway{}
_ = pkg.ApolloStruct("gateway", c)
allServices := c.AllServices
......
基本使用
接口参数校验规则
var CustomValidators = &[]pkg.Validators{
{
Tag: "int_sequence", // 自定义正则校验
RegExp: `^(\d+)(,\d+)*$`,
Msg: "{0}必须为','分隔的数字",
},
{
Tag: "fund_id",
RegExp: `(?i)^HF[0-9A-Za-z]{8}$`,
Msg: "{0}基金id格式有误",
},
{
Tag: "fixed_len", // 自定义方法校验
Handler: func(fl validator.FieldLevel) bool {
fixedLen := fl.Param()
fieldValue := fl.Field().String()
lenInt, err := strconv.Atoi(fixedLen)
if err != nil {
return false
}
return len(fieldValue) == lenInt
},
Msg: "{0}长度有误",
},
}
路由规则
var FundRoute = &pkg.Routes{
Group: "",
Rules: []pkg.Rule{
{
Method: http.MethodGet,
Route: "/fund",
Handler: controller.FundController{}.List,
DataBind: binding.Query,
},
{
Method: http.MethodGet,
Route: "/fund/:id",
Handler: controller.FundController{}.Detail,
DataBind: binding.Query,
},
......
},
}
初始化&服务启动
func init() {
componentsToInit := []bootstrap.InitConf{
{Component: bootstrap.Config, Conf: loadConfigConf},
{Component: bootstrap.DataBase, Conf: loadTracerConf},
......
}
if err := bootstrap.Initialize(componentsToInit); err != nil {
panic(err)
}
}
func main() {
srv := gin_server.New(&gin_server.Conf{
Mode: gin.DebugMode,
RegisterRoutes: []*pkg.Routes{
router.FundRoute,
},
CustomerValidators: api.CustomValidators,
PanicRecovery: true,
})
//srv.Use(......)
_ = srv.Run(":9990")
}
func loadConfigConf() *bootstrap.ConfigConf {
dir, err := os.Getwd()
if err != nil {
panic(err)
}
return &bootstrap.ConfigConf{
ConfigType: "toml",
ConfigPath: filepath.Join(dir, "example", "conf"),
ApolloConf: loadApolloConf,
InitCallback: nil,
}
}
func loadApolloConf() *bootstrap.ApolloConf {
apConf := &pkg.ApolloConfPkg{}
if err := pkg.Config.Read("apollo").Unmarshal(apConf); err != nil {
panic(err)
}
return &bootstrap.ApolloConf{
ApConf: apConf,
ApUpdateCallback: func(appId string, namespace string, changeKeys []string) {
if pkg.ApolloAlias("tracer").GetBool("enable") {
pkg.Tracer.EnableTracer()
} else {
pkg.Tracer.DisableTracer()
}
......
},
}
}
func loadDatabaseConf() *bootstrap.DatabaseConf {
configKeys := []string{"db.data_core", "db.market_operate"}
dbConfig := make(map[string]*pkg.DbPoolConfig)
for _, confKey := range configKeys {
conf := &pkg.DbPoolConfig{}
_ = pkg.ApolloStruct(confKey, conf)
dbConfig[confKey] = conf
}
return &bootstrap.DatabaseConf{
DbConf: dbConfig,
Callback: func(gormDbs map[string]*gorm.DB) {
if db, ok := gormDbs["db.data_core"]; ok {
dao.DataCore = data_core.Use(db)
}
if db, ok := gormDbs["db.market_operate"]; ok {
dao.MarketOperate = market_operate.Use(db)
}
},
}
}
相关文档
Gin
https://www.kancloud.cn/shuangdeyu/gin_book/949416
GORM
https://gorm.io/docs/query.html
GORM/GEN
https://gorm.io/gen/query.html
Apollo(配置中心)
https://www.apolloconfig.com/#/zh/README