disconf是百度开源的一套分布式配置管理平台,详情可以戳这里

尽管类似的平台不在少数,国内的奇虎、阿里等也均有类似开源实现,但它对于我们后端应用中诸多配置,在使用和管理上之方便,是直到博主进入在某大型O2O公司实习时才深有体会。

试想一下,一个应用,首先肯定有多个环境,至少,线上线下连接的数据库肯定不相同,然后,不论是出于负载均衡,还是可用性方面的考虑,线上业务很可能不是单点的,也就是部署在了多台vm,或者docker中,某天因业务需要,要修改一个配置项……

先解决前一个问题,纵然通过spring或者maven的profile都可以规避这个问题,更简单一点,写一个脚本,在启动程序时带几个跟当前环境相关的jvm启动参数,欧了;后一个问题,更简单了,配置文件一般不都在resource目录下嘛,改之、打包、部署~可……这样真的好么?

本文将通过部署disconf来更高效地解决上面的问题。Come on!补充一句,disconf分为disconf-client和disconf-web两部分,client用在我们的业务系统中,web部署在我们的服务器上,本文两部分都会涉及。

相比于其他应用,disconf的部署主要是依赖的的东西不少,而且都是比较重的,什么mysql、redis、zookeeper,好在这一些我们的其他业务系统也要用到,有些呢,甚至早就部署过了。

安装依赖

mysql和redis

作为最常见的关系数据库、内存数据库(虽然一般用作缓存了),不要说你没有哈,真没有的话,戳这里这里看我以前的博客。

tomcat和nginx

这两个家伙不比上头的数据库们罕见。其实一开始我还奇怪,为什么要同时使用两个web服务器,后来了解到,这是做法叫做“动静分离”,静态web资源依靠nginx,动态依靠tomcat,毕竟nginx在渲染静态资源时效率真的要高出不少。两者的安装和配置请戳这里这里

zookeeper

最后这个嘛,对分布式、高可用等概念稍微有一点了解的同学应该都听说过,本文暂时不会对它做深入的解释,它的安装,毕竟是可以通过ubuntu的软件源来完成的,方便了不少呢

1
2
3
4
5
# zk需要java环境,一般地,openjdk可以代替oracle jdk
apt install openjdk-8-jdk
# zookeeperd用于提供zk的启动脚本,从而以服务形式管理zk
apt install zookeeper zookeeperd

配置

其实这个副标题不是那么恰当,这一步要完成的是下载disconf-web并且修改它的配置文件来适应前边安装好的以来组件。disconf下载有那么一丁点特殊,它没有提供单独的下载地址,既然是github上的一个项目,直接clone吧

1
git clone https://github.com/knightliao/disconf.git

然后打开./disconf-web/profiles/rd目录,其中有

  • application.properties
  • jdbc-mysql.properties
  • log4j.properties
  • logback.xml
  • redis-config.properties
  • zoo.properties

共6个文件就是disconf的配置文件,我们需要依次修改。

application.properties

首先这个文件是由application-demo.properties重命名而来的,这里边配置的是服务器域名和邮件通知功能。服务器域名,官方文档上说要和后边nginx里的配置保持一致。

jdbc-mysql.properties & redis-config.properties

这两个文件看名字猜也猜得到,配置mysql和redis的,我们要修改的主要是如何连接到相应的数据库。另外官方文档要求redis必须配置双实例,就算我们的redis服务单点,也要配置两个。

log4j.properties & logback.xml

两个日志框架的配置文件,日志格式个人觉得没有什么修改的必要,但我们所有业务有统一的日志路径,所以日志路径是要修改的。因为没有细读过disconf的源代码,所以不是很清楚它是同时用了log4j和logback还是咋滴,两个文件中总共配置了3处日志,日志文件名分别是disconf-log4j.log、disconf-web.log和monitor.log。

zoo.properties

最后这个是zookeeper的配置文件,这个文件原本配置了3台机器组成的zk集群,谁让我们服务都是单点的呢(笑~),直接改成我们唯一的zk节点的ip和端口。

另外这里有点小问题,此处配置的zk节点信息,client启动时会通过web api去获取和使用,如果我们配置成zk节点的内网ip,那线下可能就访问不到,而如果配置成外网ip,线上使用时所有数据岂不是要到公网上绕一圈?我暂时没有好的办法,配置成了公网ip,再在内网主机的hosts里加一行,强行将公网ip转向内网ip,哪位同学给个更好的解决方案哈~

打包和部署

disconf提供了一个用于打包自身的脚本:.disconf-web/deploy/deploy.sh,运行脚本前要指定好配置文件的所在路径,以及打包的输出路径。

1
2
3
4
5
6
7
8
9
10
# 指定配置文件文件所在路径
ONLINE_CONFIG_PATH=/tmp/disconf/disconf-web/profile/rd
export ONLINE_CONFIG_PATH
# 指定打包输出路径
WAR_ROOT_PATH=/tmp/disconf/disconf-web/war
export WAR_ROOT_PATH
# 执行打包脚本(cd到disconf-web目录下执行)
sh deploy/deploy.sh

可能要经过一段时间的等待(毕竟要下载不少jar包),打开刚才指定的目录输出路径,可以看到是一个熟悉的web项目的结构。吐槽一句,既然部署脚本已经帮忙把war包给解压了,那为何不好人做到底,把已经没用的war包顺手删掉呢?还有打包时复制过去的配置文件同样也是多余的呀。

在正式部署之前还有一件事要做——初始化数据库,要用到的sql,disconf也都提供好了,位于./disconf-web/sql目录下,包括4个文件,执行的顺序看其中的readme吧。当然,这都是可以修改了,像什么环境啦,用户啦都可以定制得更符合我们的需要,还有许多测试数据可能也是我们不需要的。

初始化好了数据库就可以开始部署了。前面说过,disconf做了动静分离,因此部署分两个部分。先部署动态部分(tomcat),修改tomcat端口为disconf的后端端口号(这里假定本机的tomcat上就跑这么一个应用~),打开配置目录下的server.xml文件,在节点下添加这么一个虚拟主机,映射到站点根目录上

1
<Context path="" docBase="/opt/disconf" />

再部署静态部分(nginx),同样假定本机的nginx只被disconf使用,因此直接修改default站点(/etc/nginx/site-available/default文件)

1
2
3
4
5
6
7
8
9
server {
listen 80 default_server;
root /opt/disconf/html;
index index.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}

重新启动tomcat和nginx就完成了disconf的部署。注意这里完全将动态资源和静态资源分离了,这是因为我们还有另一台更前置的nginx,根据具体的uri匹配请求的资源应该被反向代理到这里的tomcat还是nginx上,因此如果到这一步要进行测试的话,记得访问动静态资源的端口号是不一样的。