天天看点

在阿里云容器服务上开发基于Docker的Spring Cloud微服务应用(六)

本文为阿里云容器服务spring cloud应用开发系列文章的第六篇。

六、集中配置管理(本文)

在传统的运维中,如果一个服务器或着运行环境升级升级,可以通过自动化脚本对服务器进行更新。随着时间的推移和需求的不断变化,可能需要运维人员登陆进入服务器进行改动。这样做虽然方便,但积累起来会造成服务器环境的"漂移",意味着自从上次代码部署后在这个服务器发生了什么改变谁都不记得了,也许微小的一个差异就会引起错误。

不变基础架构(immutable infrastructure)的意思我们不再打补丁了,也不允许运维人员登陆进入手工修改。如果服务器需要升级,那就把原来的服务停掉,删除服务器,用一个新的服务器替换。不变架构保证了线上运行的代码和配置永远是有版本控制,并且一致的。

这样做会带来一些不方便,如果一个服务需要更新一个基础配置,也需要在代码的配置文件中进行更改,构建一个新的镜像,然后把该服务的所有实例停掉进行替换。有时候为了更改一个配置信息而重新构建镜像,这件事总让人觉得有些不对。能不能应用的配置信息也集中管理起来?

spring cloud提供的集中配置管理(config server)可以解决这个问题。服务在启动的时候统一从一个集中的配置服务器中读取的配置,这样可以保证服务的代码和配置选项都不变的情况下又能够得到最新的配置信息。

我们在下面会演示如何创建config server,如何让其它服务访问config server。

注意:本文的示例程序没有包含这部分内容。如果向获得详细描述,请参见spring官方文档。

在build.gradle中引入对config server的依赖。

通过<code>@enableconfigserver</code>注解将主class声明为config server:

在<code>application.properties</code>中定义config server的侦听端口和从git中获得配置信息:

git.uri指向存储配置信息的git仓库,里面为每个服务创建一个.properties文件,例如如下文件目录结构:

<code>foo.properties</code>是为一个名字为<code>foo</code>的服务存储配置信息的文件,<code>foo-cloud.properties</code>是同样的<code>foo</code>服务在cloud profile下使用的配置信息。

假定<code>foo</code>需要一个名字为<code>message</code>的配置信息,可以在<code>foo.properties</code>中写入:

config server启动后可以通过http协议访问,获取配置信息:

所有需要从config server中获取配置信息的服务,需要在<code>build.gradle</code>中引入spring config依赖:

<code>@refreshscope</code>注解将<code>foocontroller</code> class声明为从config server中获取配置。

<code>bootstrap.yml</code>声明config server的地址和端口号,在这里分别是<code>config-server</code>与<code>8888</code>。

启动容器时,通过容器间的<code>links</code>将真正的config server和服务关联起来。

假定这个服务就上文提到的<code>foo</code>服务,那么它如何获取<code>message</code>配置呢?这也是通过注解完成。

@value("${message}")表示在应用启动时自动注入foocontroller的message变量。

通过spring config server进行配置信息同步可能有一个潜在的问题,例如上面的示例中,在<code>bootstrap.yml</code>中配置对配置服务器的访问。<code>bootstrap.yml</code>是在应用启动时解析的,如果在启动时配置服务器还没有启动则会出现依赖它的所有服务也无法成功启动。

我们这里展示的是通过阿里云的对象存储(oss)完成服务的集中配置管理。原理是所有的容器挂载oss,启动成功后容器内的应用从oss中读取配置。由于oss具有非常高的可靠性,并且对其内容的更改会被所有服务读到,非常适用于配置信息同步这个场景。

更进一步,阿里云容器服务上提供了ossfs的支持。ossfs可以把oss模拟成为文件系统,应用可以直接用传统的文件系统api访问oss,而不必使用oss api。由于一般应用都是将配置存储在文件系统中,使用ossfs意味着应用不必做任何变更就实现了配置信息的中心化管理。

下面演示如何创建oss以及挂载ossfs。

进入oss管理控制台,创建oss bucket,注意所属地域要选择容器集群所在地域,如下图所示:

在阿里云容器服务上开发基于Docker的Spring Cloud微服务应用(六)

bucket创建好后,将配置文件上传。

在阿里云容器服务上开发基于Docker的Spring Cloud微服务应用(六)

基于安全的考虑,建议进入<code>安全令牌</code>创建子账号,并记录下accesskeyid和accesskeysecret。

在阿里云容器服务上开发基于Docker的Spring Cloud微服务应用(六)

进入容器服务控制台,在<code>数据卷</code>菜单下创建新的数据卷:

在阿里云容器服务上开发基于Docker的Spring Cloud微服务应用(六)

选择刚才创建的bucket:

在阿里云容器服务上开发基于Docker的Spring Cloud微服务应用(六)

在docker-compose.yml中为服务增加如下声明:

<code>volumes</code>中,<code>foobar-config-oss</code>是前面创建的oss bucket名字,<code>/config</code>是在容器中的挂载点。

我们准备通过登陆进入容器来验证ossfs是否已经挂载成功。

首先在容器服务的控制台上点击集群<code>连接信息</code>进入连接信息页面。

在阿里云容器服务上开发基于Docker的Spring Cloud微服务应用(六)

复制环境变量配置,在你的命令行窗口配置环境变量,下载证书,将证书解压缩到工作目录。

在工作目录下运行如下命令,获得挂载ossfs的容器id:

进入容器,查看<code>/config</code>下的配置文件内容。

可以看到容器已经成功挂载ossfs。如果配置文件发生变更,上传进入oss bucket后容器就可以读到最新的内容。所以容器示例都挂载同一个数据卷,实现了配置信息的集中化管理和分布读取。

本文介绍了如何通过spring config server和阿里云的对象存储oss来进行配置信息的集中管理。