在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 ...
随机推荐
- CSS中的ul与li样式详解 list-type
转自新浪博客http://blog.sina.com.cn/u/2539885750 ul和li列表是使用CSS布局页面时常用的元素.在CSS中,有专门控制列表表现的属性,常用的有list-style ...
- python学习之路网络编程篇(第三篇)
python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. #!/usr/bin/env python # -*- coding:utf-8 -*- import t ...
- 转:rabbitmq——用户管理
原文:http://my.oschina.net/hncscwc/blog/262246?p={{currentPage-1}} 安装最新版本的rabbitmq(3.3.1),并启用managemen ...
- iOS不能交互的几种情况
alpha <=0.01 hidden = YES userInteraction = NO 父试图不允许交互,子试图也不允许交互: 在父试图可见范围内,可以交互,超出部分失效,不能交互
- Oracle12c中SQL性能优化(SQL TUNING)新特性之自动重优化(automatic reoptimization)
Oracle12c中的自动重优化 Oracle12c中的自适应查询优化有一系列不同特点组成.像自适应计划(AdaptivePlans)功能可以在运行时修改执行计划,但并不允许计划中连接顺序的改变.自动 ...
- linux系统性能监控--I/O利用率
尽管整体的处理器速度. 内存大小以及 I/O执行速度在不断提高,但 I/O操作的吞吐率和延迟性能仍然要比等价的内存访问操作低多个数量级.另外,由于许多工作负荷都拥有重要的I/O组件,I/O处理很容易成 ...
- Unity使用UGUI进行VR游戏的界面开发
原文链接:http://gad.qq.com/article/detail/7181505 本文首发腾讯GAD开发者平台,未经允许,不得转载 我不知道有多少同学是跟我一样,在开发VR游戏中,是使用的面 ...
- django+uwsgi+nginx+postgresql备忘
安装pg创建数据库xxx设置用户密码111111 apt-get install postgresql su - postgres psql create database xxx; alter us ...
- Maven 核心原理
Maven 核心原理 标签 : Java基础 Maven 是每一位Java工程师每天都会接触的工具, 但据我所知其实很多人对Maven理解的并不深, 只把它当做一个依赖管理工具(下载依赖.打包), M ...
- Spring+EhCache缓存实例(详细讲解+源码下载)
一.ehcahe的介绍 EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider.Ehcache是一种广泛使用的开源Java分布式 ...