文章目录
- 前言
- 一、配置文件功能需求
- 二、web工程设计思路
- 三、Config实现思路
前言
配置文件作用
:把需要经常修改的参数,从代码中分离出来,单独管理,方便后期维护。
开发一个web
应用,肯定需要一些基础性的配置信息,这些信息项目中一般都会使用配置文件统一管理。
图中只是一个简单的示意,随着我们项目的不断完善,后续该配置文件的信息也会越来越多,这里先简单介绍一下。
HTTP
模块:启动的端口号是多少。- 日志模块:日志级别、输出位置、日志文件名、是否打印堆栈信息,日志格式等。
DB
:连接地址和端口号、数据库名称、用户名和密码等。
实际工作中,这些配置信息我们会从代码当中分离出来。单独维护,方便后期运维修改。在整个应用加载的时候,把它加载到go
的内存当中,通常用一个Config
变量存储,后续在项目代码当中,基本上就是以如下的方式使用,比如开始可能是将服务的地址写死在代码中的,而现在我们以配置文件的方式获取变量。
//r.Run("localhost:8080",
r.Run (app.Config.HTTP.Listen)
一、配置文件功能需求
本项目中,配置文件的实现主要会考虑如下四点:
- 使用
YAML
文件格式配置,备选:toml、ini、json
- 支持多环境配置:
dev、test、prerelease、online
- 支持配置重载:
config-default.yml -→ config.yml
- 支持环境变量覆盖
第一点:本项目我们会选用yaml
格式,因为yam
l和toml
是工作配置文件用的最多的格式,ini
使用相对较少,最不推荐配置文件使用json
这种格式,它的语义语义性不是特别好,当然json
格式在前后端交互时却是首选的文件格式。
第二点:工作中项目基本都需要支持多环境配置模式,在开发和测试的时候可能是一个环境,线上用户是访问不到这个环境的代码和数据库的,而上线后则需要正式的online
环境配置,让所有用户都能访问到。
第三点:它支持一个重载模式。所谓的重载,就是有一份基础的公共的配置,这份配置里面配置的参数是通用的,而且经常不更改的,但是后面我有一个文件,可能是会就像上面第二点说的一样,针对这些不同的环境,有不同的配置参数。那但凡在这些配置参数里面,如果我发现这两个文件里面都有相同的配置字段的话,那后面这个文件中的字段,值是可以覆盖前面这个值,这样的话,在不同的环境里面,就可以使用不同的字段对它进行覆盖,使用起来就会非常灵活或方便。
第四点:支持环境变量覆盖是一个附加的锦上添花的功能,平常的工作当中也会这么用,比如一个项目启动的时候,有一些字段,可能是写死在本地的一些配置文件当中,但有时候希望通过环境变量的方式,把配置文件当中某个值进行二次覆盖,那这样就可以更好的发挥这个配置文件的灵活性。
本项目中我们会把这四点一一实现。
二、web工程设计思路
先不急于实现,我们先来看一下web
应用项目工程的设计思路。整体上我们把一个项目就当成一个APP
,也就是一个应用。我们会把所有核心的代码都放在这个app
目录下,app.go
则作为整个项目应用入口。我们会把各个组件都挂载到这个APP
应用下,也就是说我们所有核心的组件都是app
这个全局的变量的一个子模块,这些组件从服务初始化启动的时候,生命周期就随着整个应用
。那为什么要这样设计呢?因为这样后续使用这些模块的时候,在这个项目的任何位置,都可以使用。下图其实也是本项目的一个基本纲要。
比如要使用某一个配置下的一些值,那可能就是像app.Config.HTTP.Listen
这种直接点式的链式语法,再比如说我想使用log
模块打印日志,可以在任何一个代码层面使用app.Log().Error(""server error")
来完成。同样,db
、redis
等等,都是以这种思路使用。
//获取某个配置
app.Config.HTTP.Listen
// 使用日志模块
app.Log().Error(""server error")
三、Config实现思路
程序入的口的话肯定是main.go
文件,在main.go
里面,我们会对整个应用做一些初始化,而这个初始化我们可以把它封装在app
包的Init
函数中。初始化工作的第一步肯定是做配置文件的加载,因为后续的DB、Redis
等的初始化都依赖配置文件中的信息。最终把加载的内容保存到一个配置结构体,然后挂载到app.Config
这个变量中。
正式进入下篇配置文件加载实战前,希望大家已经掌握了如下知识点:
- 命令行参数解析:服务启动的时候,我们会给它传一些命令行的参数,可以用
go
中的flag
包解析。 - 文件操作:文件的读取、路径获取等。
yaml
解析:解析yaml
配置文件。- 利用
Struct
自定义tag
和反射(reflect
)实现环境变量重载。