在go中使用json作为主要的配置格式
最近在用go重构,在先前的代码中,我们使用的ini文件进行配置,但是因为很多历史遗留问题,导致配置混乱,维护困难,自然也需要考虑重构了。
通用配置格式
通用的配置格式有很多,常用的就有ini,json,yaml,xml等,当然为了通用我们不考虑自定义的配置格式。那如何选择呢?
首先,xml我们就不用考虑了,到现在为止我都没觉得用这玩意配置起来有多方便,反而很臃肿,可能java系的童鞋会比较青睐。
再来考虑ini,ini文件对于简单应用的配置可以说是非常方便的,如果配置没有太多的层次结构,使用ini就能完全满足我们的需要,即使有,我们也能够通过加入特定前缀来解决。譬如,我们可能有如下redis配置:
[ModuleA]
persistent_redis_addr = 127.0.0.1:6379
persistent_redis_password = admin
cache_redis_addr = 127.0.0.1:6380
cache_redis_password = admin
然后,需求变化了,我们需要另一个持久化redis服务来做相关事情,于是配置就可能变成了下面这样:
[ModuleA]
persistent_redis_addr = 127.0.0.1:6379
persistent_redis_password = admin
persistent2_redis_addr = 127.0.0.1:6379
persistent2_redis_password = admin
cache_redis_addr = 127.0.0.1:6380
cache_redis_password = admin
虽然通过前缀命名能解决层级问题,但总觉得是对程序员不怎么友好的。
why json
剩下的就是json和yaml,可以这么说,这两个都算是比较好的轻量级配置格式,而且对程序员非常友好,而且go里面都可以通过定义struct,将层级结构的配置映射到相应的struct里面。
但是我还是决定选择json作为我们go代码的默认配置格式,最主要的原因在于go的json包有一个杀手级别的RawMessage实现。而这个在我能找到的yaml包中没有。
RawMessage主要是用来告诉go延迟解析用的。当我们定义了某一个字段为RawMessage之后,go就不会解析这段json,这样我们就可以将其推后到各自的子模块单独解析。
假设有一个功能,后台存储可能是redis或者mysql,但是只会使用一个,可能我们会按照如下方式写配置:
redis_store : {
addr : 127.0.0.1
db : 0
},
mysql_store : {
addr : 127.0.0.1
db : test
password : admin
user : root
}
store : redis
对应的class为
type Config struct {
RedisStore struct {
Addr string
DB int
}
MysqlStore Struct {
Addr string
DB string
Password string
User string
}
Store string
}
如果这时候我们在增加了一种新的store,我们需要在Config文件里面在增加一个新的field,但是实际我们只会使用一种store,并不需要写这么多的配置。
我们可以使用RawMessage来处理:
type Config struct {
Store string
StoreConfig json.RawMessage
}
如果使用redis,对应的配置文件为
store: redis
store_config: {
addr : 127.0.0.1
db : 0
}
如果使用mysql,对应的配置文件为
store: mysql
store_config: {
addr : 127.0.0.1
db : test
password : admin
user : root
}
go读取配置文件之后,并不会处理RawMessage对应的东西,而是由我们代码自己对应的store模块去处理。这样无论配置文件怎么变动,store模块做了什么变动,都不会影响Config类。
而在各个模块中,我们只需要自己定义相关config,然后可以将RawMessage直接解析映射到该config上面,譬如,对于redis,我们在模块中有如下定义
type RedisConfig config {
Addr string `json:"addr"`
DB int `json:"db"`
}
func NewConfig(m json.RawMessage) *RedisConfig {
c := new(RedisConfig)
json.Unmarshal(m, c)
return c
}
json的不足
使用json也还有很多蛋疼的地方,最大的问题就在于注释,在json中,可不能这样写:
{
//this is a comment
/*this is a comment*/
}
但是,我们又不可能不写一点注释来说明配置项是干啥的,所以,通常采用的是引入一个comment字段的方式,譬如:
{
"_comment" : "this is a comment",
"key" : "value"
}
另外,json还需要注意的就是写的时候最后一项不能加上逗号,这样的json会因为格式错误无法解析的。
{
"key" : "value",
}
最后那个逗号可是不能要的,但是实际写配置的时候我们可是经常性的随手加上了。
但是,总的来说,json对于go的项目还是很友好的,我不光在项目中推行了,在自己的开源项目中,也大量的采用了json作为主要的配置文件。
在go中使用json作为主要的配置格式的更多相关文章
- jquery 解析数据库中的json日期为正常的格式
//在action从后台数据库中请求获得日期以后,得到的是json格式的数据,因此要解析才能显示在前台1.在jsp页面写的代码如下:<html> <script> Date.p ...
- C#中Newtonsoft.Json 序列化和反序列化 时间格式
步骤 引用 using Newtonsoft.Json; using Newtonsoft.Json.Converters; 格式配置 IsoDateTimeConverter timeFormat ...
- 如何正确的使用json?如何在.Net中使用json?
什么是json json是一种轻量级的数据交换格式,由N组键值对组成的字符串,完全独立于语言的文本格式. 为什么要使用json 在很久很久以前,调用第三方API时,我们通常是采用xml进行数据交互,但 ...
- C#中的Json的序列化和反序列化
Json是一种通用的数据格式,我们在数据交换的时候,经常会用到,下面介绍c#中的json序列化和反序列化,当然也可用在asp.net,silverlight,wpf中.我们在下面实例讲解如何进行Jso ...
- SpringMVC中使用Json传数据
在web项目中使用Json进行数据的传输是非常常见且有用的,在这里介绍下在SpringMVC中使用Json传数据的一种方法,在我的使用中,主要包括下面四个部分(我个人喜好使用maven这类型工具进行项 ...
- PHP中生成json信息的方法
<?php //php中生成json信息 //json_encode(数组/对象) $color = array('red','blue','green'); //[索引数组] echo jso ...
- 【ASP.NET Web API教程】6.2 ASP.NET Web API中的JSON和XML序列化
谨以此文感谢关注此系列文章的园友!前段时间本以为此系列文章已没多少人关注,而不打算继续下去了.因为文章贴出来之后,看的人似乎不多,也很少有人对这些文章发表评论,而且几乎无人给予“推荐”.但前几天有人询 ...
- Asp.Net Web API 2第十三课——ASP.NET Web API中的JSON和XML序列化
前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文描述ASP.NET W ...
- JMeter中返回Json数据的处理方法
Json 作为一种数据交换格式在网络开发,特别是 Ajax 与 Restful 架构中应用的越来越广泛.而 Apache 的 JMeter 也是较受欢迎的压力测试工具之一,但是它本身没有提供对于 Js ...
随机推荐
- ubuntu批量更改文件权限
重装系统之后,把文件从windows分区拷到linux分区发现所有文件的权限全是777,在终端下看到所有文件的颜色都很刺眼,文件有很多,一个一个改不现实,所以写了一段python脚本批量更改文件权限. ...
- 使用RedisDesktopManager工具,解决连接失败问题
今天在云服务器上搭建好了redis环境,想用RedisDesktopManager工具去连接一下,结果连接不上,显示如下图: 我确保了服务器防火墙关闭,又在redis配置文件中设置了requirepa ...
- Java面试19|过于深入的问题
1.synchronized关键字的实现原理 可以参考:http://www.jianshu.com/p/c5058b6fe8e5 2.CAS是由Unsafe类的compareAndSwap()方法实 ...
- CMCC验证绕过POC
大学的时候无意间发现绕过CMCC验证的方法(贫穷使人进步...),写了段POC脚本,时过两年,漏洞应该已经失效了(我猜 --),刚刚发现有人私信问我要,都那么久了鬼还记得写的什么啊,但确实看到了又不能 ...
- Numpy函数学习--genfromtxt函数
genfromtxt函数 今天学习时遇到了genfromtxt函数 world_alcohol = numpy.genfromtxt("world_alcohol.txt",del ...
- MongoDB 高级索引
考虑以下文档集合(users ): { "address": { "city": "Los Angeles", "state&qu ...
- Docker的名字空间
名字空间是 Linux 内核一个强大的特性.每个容器都有自己单独的名字空间,运行在其中的应用都像是在独立的操作系统中运行一样.名字空间保证了容器之间彼此互不影响. pid 名字空间 不同用户的进程就是 ...
- Unity3D开发注意事项
最近给组里定Unity开发注意事项,参考了@陆泽西在群里分享的[前端开发规范],结合自己工作中的经验,整理一下,下面不少条款都是我们要求在开发中必须遵守的. 资源: 图片统一为png格式,纹理属性:T ...
- javaweb异常提示信息统一处理(使用springmvc,附源码)
一.前言 后台出现异常如何友好而又高效地回显到前端呢?直接将一堆的错误信息抛给用户界面,显然不合适. 先不考虑代码实现,我们希望是这样的: (1)如果是页面跳转的请求,出现异常了,我们希望跳转到一个异 ...
- Swagger API接口管理
介绍 Swagger API框架,用于管理项目中API接口,属当前最流行的API接口管理工具. Swagger功能强大,UI界面漂亮,支持在线测试等! Swagger包 ...