Gin 简易项目配置中心的实现

Gin 简易项目配置中心的实现

转眼间,从16年只有一台服务器就需要搭建出 LNMP 环境来完成项目的部署,到今天自身+公司的发展,一台服务器已经无法满足业务大量并发的需要,在很多项目上我们已经进行了几台或者几十台服务器进行分布式负载部署了。

但那么多年没太大改变的还是我们对配置文件的处理,一开始入行阶段,还是同大家一样,通过拖拉的方式把项目的代码拉进去服务器,后面自动部署后则和代码一起放到了Git仓库上。

一些项目是存在测试+正式环境的,比如 MySQL、Redis 的连接地址则是不一样的,我尝试过在测试环境的系统变量上加上 HONGFS_DEBUG=1 来进行一个区分,然后我统一写在 .env 文件中,可能我不太了解其他人,但我们的 .env 文件都是 ini 格式的,内容由节、键、值构成。

1
2
[节]
键=值

然后在项目的 config 文件夹中去判断是不是有环境变量 HONGFS_DEBUG=1 来确定我们要使用哪部分的配置信息。

1
2
3
4
5
6
7
8
9
10
11
if (isset($_SERVER['HONGFS_DEBUG']) && $_SERVER['HONGFS_DEBUG'] == 1) {
// 测试环境
return [
'db_address' => Env::get('db.address'),
];
}

// 正式环境
return [
'db_address' => Env::get('db_release.address'),
];

不过后面发现这样子写,在开启了 opcache 后会获取不到 HONGFS_DEBUG 信息,查了官方文档,说Fast CGI 之类的 SAPI 中运行,则此函数将始终返回由 SAPI 设置的环境变量的值,然后我们只能换回之前的 IP 判断方式,我们测试服务器就只有一个。

最近在换工作,所以比较有时间来改进之前的问题。配置中心也看了阿里云的 ACM 或者其他,看起来对我们这种小规模企业还是比较麻烦的,所以觉得还是自己写一个。自己写一个也不想太麻烦,而且自己现在也是 php 往 golang 方向发展,以后的工作也不太清楚还会用哪些框架,总的来说还是希望这个程序可以比较独立而不需要受它们的影响。其实,需要考虑的东西还是挺多的。

安全 从业6年,一直都是享受云发展的红利,目前只考虑阿里云的 ECS,轻量我也不考虑。因为我们需要通过 ECS 提供的内网 API 来获取服务器基本信息来完成我们的鉴权操作。例如我会获取实例的 ID 和所在的地域,然后通过 ECS API 接口来查询该服务器实例是否存在,从而验证请求的来源是否为合法的。当然,实例 ID 因为是阿里云随机生成的,我们也不考虑由你自身泄露的情况(或者你把函数计算设置为只能 VPC 内访问)。
格式 不去限制文件的格式,它可以是 json xml ini 再或者是其他,由你自行上传到阿里云对象存储桶中去。
编辑 借助阿里云对象存储工具的 ossbrowser,你可以进行可视化的编辑文件,不过到底支不支持这个文件格式则要看工具了的。
部署 借助阿里云函数计算,减少了我们的服务器购买、维护成本,天然的支持弹性、并发。
获取 获取则需要通过实例的 ID 和地域信息进行验证后,根据你请求的 name 参数来下载指定文件然后返回文件内容。
更新 实时更新做起来成本其实是比较高的,不过可以借助 crontab 去定时重新获取配置内容,不过你要是开启了 opcache 之类记得做好清除工作。
限频 阿里云的 ECS API 限制了一分钟最多 1000 次请求,不过我们做了一些缓存的,理论上我们部署在 serverless 中是可以能力很强的,但我们也要考虑到外部 API 的限制,所以如果外部 API 被限制了,可以尝试减少一直请求更新的频率,因为请求好像是可能不会继续走同一个容器的,所以我们的缓存有时候也不会有效果的。

流程图 - 使用亿图图示绘制

如何部署?

为了方便,文章就不直接贴上代码了,页面下发提供了源码和打包好了的压缩包。压缩包是可以直接上传然后使用的。源码自行打包是需要添加执行权限的,可以借助我写的工具

接着就是上传代码了,你需要先前往阿里云对象存储创建一个存储桶,然后前往函数计算创建一个函数,运行环境是 Custom Runtime,请求处理程序类型是 HTTP,剩下的可以看我之前关于函数计算的文章,差不多就只有那些东西需要配置。

接着配置几个熟悉的环境变量才能跑起来。

1
2
3
4
access_key_id=
access_key_secret=
oss_bucket= # 存储桶名称
oss_region= # 存储桶地域

怎么跑?

首先要拿到访问的链接,然后我们的设计就是只能在 ECS 里面进行访问。会变动的参数就只有 name 吧。name 其实就是一个文件的相对路径。

这两个 100 的地址是获取服务器信息的,不需要动。

1
$ wget "https://env.tools.hongfs.cn/?name=hongfs.ini&id=$(curl http://100.100.100.200/2016-01-01/meta-data/instance-id)&region=$(curl http://100.100.100.200/2016-01-01/meta-data/region-id)" -O .env

下载:

源码

压缩包

写在最后:

今天是儿童节,六年前的今天正式开始了实习,从一开始的前端到今天的全栈,从 HTML 到今天的 PHP Python Node.js Golang,学了很多语言,也感悟了语言可能不是最重要的,更重要还是对业务需求的理解,才能更好、更快的去处理业务。也见证了 WEB 的发展到今天,也迷茫了,未来我们的出路在哪里呢?

往上