读取配置文件

1. 主函数中增加配置初始化入口

  1. 先导入viper包
import (..."github.com/spf13/pflag""github.com/spf13/viper""log")
  1. 在 main 函数中增加了 config.Init(*cfg) 调用,用来初始化配置,cfg 变量值从命令行 flag 传入,可以传值,比如 ./apiserver -c config.yaml,也可以为空,如果为空会默认读取 conf/config.yaml。
 if err:=config.Init(*cfg) ;err != nil {panic(err)}
  1. 将相应的配置改成从配置文件config.yaml(配置内容如下)读取,例如程序的端口号,ip地址,运行模式,
runmode: debug                 # 开发模式, debug, release, test
addr: :8080                  # HTTP绑定端口
name: apiserver              # API Server的名字
url: http://127.0.0.1:8080   # pingServer函数请求的API服务器的ip:port
max_ping_count: 10           # pingServer函数try的次数

完整代码如下:

import (..."github.com/spf13/pflag""github.com/spf13/viper""log")
var (cfg = pflag.StringP("config", "c", "", "apiserver config file path.")
)
func main() {pflag.Parse()if err:=config.Init(*cfg) ;err != nil {panic(err)}// Create the Gin engine.g := gin.New()gin.SetMode(viper.GetString("runmode"))middlewares := []gin.HandlerFunc{}// Routes.router.Load(// Cores.g,// Middlwares.middlewares...,)// Ping the server to make sure the router is working.go func() {if err := pingServer(); err != nil {log.Fatal("The router has no response, or it might took too long to start up.", err)}log.Print("The router has been deployed successfully.")}()log.Printf("Start to listening the incoming requests on http address: %s", viper.GetString("addr"))log.Printf(http.ListenAndServe(viper.GetString("addr"), g).Error())
}

2. 解析配置的函数

  1. func Init(cfg string) 如果cfg不为空,加载指定配置文件,否则加载默认配置文件,并且调用监控配置文件的函数。
func Init(cfg string) error {c := Config {Name: cfg,}// 初始化配置文件if err := c.initConfig(); err != nil {return err}// 监控配置文件变化并热加载程序c.watchConfig()return nil
}
  1. func (c *Config) watchConfig通过该函数的 viper 设置,可以使 viper 监控配置文件变更,如有变更则热更新程序。所谓热更新是指:可以不重启 API 进程,使 API 加载最新配置项的值。
func (c *Config) watchConfig() {viper.WatchConfig()viper.OnConfigChange(func(e fsnotify.Event) {log.Printf("Config file changed: %s", e.Name)})
}
  1. func (c *Config) initConfig() error调用viper包提供的方法,读取所需要的配置
func (c *Config) initConfig() error {if c.Name != "" {viper.SetConfigFile(c.Name) // 如果指定了配置文件,则解析指定的配置文件} else {viper.AddConfigPath("conf") // 如果没有指定配置文件,则解析默认的配置文件viper.SetConfigName("config")}viper.SetConfigType("yaml") // 设置配置文件格式为YAMLviper.AutomaticEnv() // 读取匹配的环境变量viper.SetEnvPrefix("APISERVER") // 读取环境变量的前缀为APISERVERreplacer := strings.NewReplacer(".", "_") viper.SetEnvKeyReplacer(replacer)if err := viper.ReadInConfig(); err != nil { // viper解析配置文件return err}return nil
}

完整代码如下:

package configimport ("log""strings""github.com/fsnotify/fsnotify""github.com/spf13/viper"
)type Config struct {Name string
}func Init(cfg string) error {c := Config {Name: cfg,}// 初始化配置文件if err := c.initConfig(); err != nil {return err}// 监控配置文件变化并热加载程序c.watchConfig()return nil
}func (c *Config) initConfig() error {if c.Name != "" {viper.SetConfigFile(c.Name) // 如果指定了配置文件,则解析指定的配置文件} else {viper.AddConfigPath("conf") // 如果没有指定配置文件,则解析默认的配置文件viper.SetConfigName("config")}viper.SetConfigType("yaml") // 设置配置文件格式为YAMLviper.AutomaticEnv() // 读取匹配的环境变量viper.SetEnvPrefix("APISERVER") // 读取环境变量的前缀为APISERVERreplacer := strings.NewReplacer(".", "_") viper.SetEnvKeyReplacer(replacer)if err := viper.ReadInConfig(); err != nil { // viper解析配置文件return err}return nil
}// 监控配置文件变化并热加载程序
func (c *Config) watchConfig() {viper.WatchConfig()viper.OnConfigChange(func(e fsnotify.Event) {log.Printf("Config file changed: %s", e.Name)})
}

数据库连接

1.ORM框架

apiserver 用的 ORM 是 GitHub 上 star 数最多的 gorm,相较于其他 ORM,它用起来更方便,更稳定,社区也更活跃。 gorm有如下特性:

  • 全功能 ORM (无限接近)
  • 关联 (Has One, Has Many, Belongs To, Many To Many, 多态)
  • 钩子 (在创建/保存/更新/删除/查找之前或之后)
  • 预加载
  • 事务
  • 复合主键
  • SQL 生成器
  • 数据库自动迁移
  • 自定义日志
  • 可扩展性, 可基于 GORM 回调编写插件
  • 所有功能都被测试覆盖
  • 开发者友好

2.建立数据连接

1.先配置文件中,配置数据库相关参数

db:name: db_apiserveraddr: 127.0.0.1:3306username: rootpassword: root
docker_db:name: db_apiserveraddr: 127.0.0.1:3306username: rootpassword: root
  1. 创建数据库连接结构体,并且初始化连接
type Database struct {Self *gorm.DBDocker *gorm.DB
}
func (db *Database) Init() {DB = &Database{Self:   GetSelfDB(),Docker: GetDockerDB(),}
}

3.根据用户名密码等参数,打开连接

func openDB(username,password,addr,name string) *gorm.DB  {config :=fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=%t&loc=%s",username,password,addr,name,true,//"Asia/Shanghai"),"Local")db, err := gorm.Open("mysql", config)if err!=nil{log.Printf("Database connection failed. Database name: %s", name)}setupDB(db)return db
}

Go语言实战 : API服务器 (4) 配置文件读取及连接数据库相关推荐

  1. Go语言实战 : API服务器 (2) 运行流程

    1.API服务器的总流程 分为两步: 启动API服务器 API服务器对HTTP请求进行处理 2.API服务器启动流程 解析配置文件,利用配置文件完成对服务器的初始化配置 初始化logger,开启日志记 ...

  2. Go语言实战 : API服务器 (8) 中间件

    为什么需要中间件 我们可能需要对每个请求/返回做一些特定的操作,比如 记录请求的 log 信息 在返回中插入一个 Header 部分接口进行鉴权 这些都需要一个统一的入口.这个功能可以通过引入 mid ...

  3. 【Go API 开发实战 6】基础 2:配置文件读取

    配置文件读取 本节核心内容 介绍 apiserver 所采用的配置解决方案 介绍如何配置 apiserver 并读取其配置,以及配置的高级用法 本小节源码下载路径:demo02 可先下载源码到本地,结 ...

  4. go语言实战(猜数字+在线词典+服务器)

    go语言实战案例 1.猜数字游戏 2. 词典 2.1 request 2.2 response 2.3 修改写死的单词为用户可写的word 2.4 细节优化 2.4.1 防止403.404等状态码 2 ...

  5. 启动服务错误5拒绝访问_【Go API 开发实战 5】基础1:启动一个最简单的 RESTful API 服务器...

    启动一个最简单的 RESTful API 服务器 本节核心内容 启动一个最简单的 RESTful API 服务器 设置 HTTP Header API 服务器健康检查和状态查询 编译并测试 API 本 ...

  6. 【Go API 开发实战 5】基础1:启动一个最简单的 RESTful API 服务器

    本节核心内容 启动一个最简单的 RESTful API 服务器 设置 HTTP Header API 服务器健康检查和状态查询 编译并测试 API 本小节源码下载路径:demo01 可先下载源码到本地 ...

  7. 游戏读取服务器配置文件失败,游戏服务器怎么配置文件

    游戏服务器怎么配置文件 内容精选 换一换 伸缩策略的类型为告警策略时,支持使用Agent监控指标触发伸缩活动.Agent监控即操作系统监控,相比基础监控,操作系统监控可以为用户提供服务器的系统级.主动 ...

  8. 【C 语言】文件操作 ( 配置文件读写 | 框架搭建 | 写出或更新配置文件 | 读取配置文件 )

    文章目录 一.写出或更新配置文件 二.读取配置文件 一.写出或更新配置文件 写出或更新配置文件 : 首先 , 使用 字符数组 存储 键值对 信息 ; // 写出 或 更新 的配置项// 数组声明会后 ...

  9. Redis由浅到深层次讲解和springboot实战(服务器层面的搭建部署)

    Redis由深层次讲解到springboot实战 一.Nosql概述 为什么使用Nosql 1.单机Mysql时代 90年代,一个网站的访问量一般不会太大,单个数据库完全够用.随着用户增多,网站出现以 ...

最新文章

  1. 新浪新闻改版了,是到了告别的时候了吗?
  2. Hadoop |集群的搭建
  3. java 引用队列_Java中的方法队列
  4. sqoop将hive导出到mysql_Sqoop hive导出到mysql[转]
  5. 带头结点的单链表的初始化,建立,插入,查找,删除
  6. Cisco 交换机配置文件存放位置及管理要点
  7. 用户态文件系统fuse学习
  8. 了解Node.js-to-Angular 套件组件
  9. sql处理null值
  10. 第一部分 第五章 数组 1102-1149
  11. 云计算服务器搭建教程,如何搭建云计算平台_搭建云计算平台步骤
  12. freeradius mysql ad_freeradiusmysql简单配置一例
  13. Leetcode 995. Minimum Number of K Consecutive Bit Flips
  14. After Effects CS4 \CS5\CS6\CC2015\CC2017\CC2018\CC2019安装包及教程
  15. mysqlin查询的java写法_[转载]常用的shell脚本
  16. 组合导航(二):导航参考坐标系
  17. 抢票原理通俗解释,​候补购票是什么?你还在交智商税吗?
  18. .NET 4.0安装提示一般信任关系失败
  19. 008-阈下意识|识别商场上的圈套
  20. Python内置函数 vars()函数

热门文章

  1. TCP协议-如何保证传输可靠性
  2. 【Leetcode | 1】3. 无重复字符的最长子串
  3. 文件在线预览 图片 PDF Excel Word
  4. spring分布式事务学习笔记(2)
  5. java常用设计模式一:单例模式
  6. JSP过滤器Filter配置过滤类型汇总
  7. Gigaset ME/pure/pro体验:就是这个德味
  8. 上周热点回顾(6.14-6.20)
  9. ThreadPoolExecutor线程池 + Queue队列
  10. Spring Cloud Sleuth进阶实战