使用阿里云ACM简化你的Spring Cloud微服务环境配置管理

摘要:本文我们就如何使用阿里云ACM这样的配置管理产品在Spring Cloud中替代Spring Cloud Config帮助简化环境配置管理做一个简单的示例,帮助你理解基于ACM来简化微服务环境配置管理的方案,并会简单比较一下ACM与Spring Cloud Config方案的优劣。

1. 配置的环境属性

毫无疑问,在系统持续交付的过程中,系统最终运行环境的多样性及复杂性毫无疑问增加了我们在配置管理工作上的负担,有时候,甚至不夸张的说,配置就是因环境而生。

这在Eugen Paraschiv的博文Configuration Must Be Environment Specific里有简单的阐述,在我的博文《现代应用架构中的配置管理面临的挑战》的容器化、调度与配置管理小节也有深入的阐述。

如果要问,是什么导致了我们应用的构建物(artifact)在各个环境不能保持一样,有时候Docker无法轻易达成“Build Once, Run Anywhere!"的承诺,其答案往往就是环境配置的差异,为帮助你理解,举一些简单的例子:

在开发环境中将logLevel设置为DEBUG,在预发环境logLevel设置为INFO,生产环境里logLevel设置为WARNING

在开发环境中使用4核8G的机器跑数据库,而在生产中用32核96G机器跑数据库

在日常环境执行线程池的最大线程数应该设置为15,而生产环境上这个值应该大一点,默认设为150

在线上环境中,中心机房,应用数据源需要连接A库,而深圳机房,应用应该就近连接使用B库

只有在小淘宝环境,双向同步开关才应该关闭

这次的改动有点大,新的特性仅在线上的杭州单元把该特性开放出来,其它的单元环境先不要开放出来

本文我们就如何使用阿里云ACM这样的配置管理产品在Spring Cloud中替代Spring Cloud Config帮助简化环境配置管理做一个简单的示例,帮助你理解基于ACM来简化微服务环境配置管理的方案,并会简单比较一下ACM与Spring Cloud Config方案的优劣。

2. 场景故事

为了帮助理解需求和场景,在日常工程实践中,我们一般会用用户故事(User Story)的方式,预设一个简单的场景,以此来做阐释和交流,熟悉微服务历史的兄弟一定熟悉下面这张早期的布道图:

本文中我们就以Movie Service为例,假设我们需要从关系数据库MySQL(RDS)检索所有电影信息列表,但是在测试环境、预发和生产环境我们需要使用不同的数据库,因为只有生产库才需要顶配的机器。这样我们的应用需要在不同的环境配置不同的数据源配置、连接池配置、数据库安全配置等等,我们会介绍如何基于阿里云ACM的Namespace映射不同环境的能力,为movie service在不同运行环境设置不同的数据源配置。

如下图所示:

3. 创建微服务 Movie Service

新建Spring Boot Starter 微服务应用 movie service

movie service的业务逻辑很简单,从MySQL(RDS)里列出所有的movie列表,如下简图所示:

这里我们创建了一个标准的jpa应用(类似Spring官网的样例工程Accessing data with MySQL,我们的工程结构如下图所示:

引入JPA、MySQL、连接池HikariCP以及WEB依赖

org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-data-jpamysqlmysql-connector-javaruntimecom.zaxxerHikariCP2.7.6

创建 MySQL(RDS) 数据库及用户

mysql> create database db_example; -- Create the new databasemysql>create user'springuser'@'localhost'identified by'ThePassword'; -- Creates the usermysql>grant all on db_example.* to'springuser'@'localhost'; -- Gives all the privileges to the new user on the newly created database

具体可参考Accessing data with MySQL中的 'Create the database'小节

创建 WEB Controller


package com.alibaba.demo.microsvc.controller;

import org.springframework.beans.factory.annotation.Autowired;

org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import org.springframework.web.bind.annotation.RestController;

importcom.alibaba.demo.microsvc.dao.MovieRepository;

import com.alibaba.demo.microsvc.model.Movie;

@RestController

public class MovieController {

@AutowiredMovieRepository movieRepository;@RequestMapping("/list-movies")public @ResponseBody Iterable listMovies() {returnmovieRepository.findAll();  }}

4. 在ACM中使用Namespace创建隔离的环境配置

注: 在阿里云上使用ACM的前提是开通了该项服务,具体开通流程可以参考文档ACM快速入门,开通服务并登陆之后,即可进入ACM 控制台创建命名空间及配置

在ACM中创建3个环境 (dev,stage,prod)

为 dev,stage,prod 不同环境分别创建配置

注意 我们完成了什么?

在上一步中,我们为相同配置项针对不同环境的设置了不同的值,例如 'spring.datasource.url'这个配置项,我们通过设置不同的url来为各环境连接不同的数据库,并且仅在生产环境开启SSL (useSSL=true)

dev:        spring.datasource.url=jdbc:mysql://localhost:3306/db_example?useSSL=false>        prod:        spring.datasource.url=jdbc:mysql://30.5.101.169:3306/db_example?useSSL=true>   

同时,我们也为生产环境(prod)设置了更大的数据库连接池和更小的连接超时时间

dev:        spring.datasource.hikari.connection-timeout=60000        spring.datasource.hikari.maximum-pool-size=10>        prod:        spring.datasource.hikari.connection-timeout=15000        spring.datasource.hikari.maximum-pool-size=200>   

而为了方便开发调试,我们仅在开发环境打开了SQL Trace

dev:        spring.jpa.show-sql=true

5. Movie Service与配置中心ACM集成

现在我们将集成Movie Service与ACM以便从ACM中获取对应环境的配置. 关于如何在Spring Cloud中使用ACM,具体可以参考ACM官方文档开发指南 > SDK 参考 > Spring Cloud ACM

为movie service引入ACM依赖

com.alibaba.cloudspring-cloud-starter-acm1.0.1

在application.properties配置ACM连接信息、namespace、accessKey、secretKey等信息

spring.application.name=movie-servicespring.application.group=com.alibaba.cloud.acm  alibaba.acm.endpoint=acm.aliyun.comalibaba.acm.namespace=alibaba.acm.accessKey=alibaba.acm.secretKey=

注意: 你可以在ACM的'命名空间详情'或者'配置的示例代码'里找到你的namespace_id,accessKey,secretKey等信息,如下图所示:

6. 在浏览器里访问Movie Service

7. 查看ACM配置推送刷新信息

如果在movie service引入了spring-boot-starter-actuator依赖并且在application.properties设置了management.security.enabled=false,可以通过端点http://<>/acm看到应用的配置消费及刷新情况,如下图:

也可以在ACM控制台上查看配置的推送轨迹、配置版本等信息,具体使用方法可参考ACM官方文档,在此不再赘述。

8. ACM与Spring Cloud Config简单对比

对比项Spring Cloud Config阿里云ACM

Spring Cloud 无缝集成支持支持

源码分发方式开源即将开源

收费模式免费免费

大规模(超10万配置)生产验证无公开的大规模生产验证案例阿里巴巴数据中心生产环境超百万级配置,每天超亿级配置变更推送,双11等严苛场景验证

配置管控UI控制台无控制台,依赖IDE,GIT等三方工具专业的配置管理UI控制台

多语言支持主要支持java生态,无其它语言的原生客户端支持nodejs,c++等原生多语言客户端

多机房、同城双活、异地多活、多可用区等架构依赖GIT 等能力支持,官方无明确说明支持

配置变更推送依赖RabbitMQ/KAFKA内置的推送机制,无外部依赖

大规模推送时效依赖GIT Web Hook等SLA,WEB HOOK在企业级大规模生产能力待验证工业级、毫秒级

配置变更审计能力弱内置的审计机制(审计能力符合国家安全等保三级标准)

推送轨迹无法查看配置推送到客户端的实时监测有配置变更推送轨迹帮助监控配置变更推送状况

数据隔离application,profile,label,git repo等隔离策略除Spring Cloud提供的隔离级别,还提供多租户,app,data_id,group等多级隔离策略

生产运维成本高(必须对GIT/RabbitMQ等有足够的知识储备和人才储备)低(无三方组件依赖)

高可用N/A(客户自己兜底)99.99%(阿里云兜底)

安全通信支持SSL支持SSL

容灾2级(存储,server缓存)3级,多了客户端本地容灾能力

9. 扩展思考 - 为什么不把配置放到应用自身的jar包里?

在我的博文《现代应用架构中的配置管理面临的挑战》里有长篇幅的侧面论述。

如果测试、生产因为配置打出来的包不一样,如何保证你的测试是有效的?

关注微服务的开发者一定拜读过下面这本微服务圣经![微服务设计](https://img.alicdn.com/5476e8b07b923/TB1fM0tngnH8KJjSspcXXb3QFXa)在上书中的第6.7及6.8小节对于环境和配置有非常精彩的阐述,这里将原文引用在此> **6.8 服务配置**>

>服务需要一些配置。理想情况下,这些配置的工作量应该很小,而且仅仅局限于环境间配置的差异。如果你的配置修改了很多服务的基本行为,或者不同环境之间的配置差异很大,那么你可能就只能在一套环境中发现某个特定的问题,这是极其痛苦的事情。>所以,如果存在不同环境之间的配置差异,应该如何在部署流程中对其进行处理呢?一种方法是对每个环境创建不同的构建物,并把配置内建在该构建物中。刚开始看这种方法好像挺有道理。配置已经被内建了,只需要简单的部署,它应该就能够正常工作了,对吧?其实这是有问题的。还记得持续交付的概念吗?我们想要创建一个构建物作为候选发布版本,并使其沿着流水线向前移动,最终确认它能够被发布到生产环境。想象一下,我构建了一个Customer-Service-Test构建物和Customer-Service-Prod构建物。如果Customer-Service-Test构建物通过了测试,但我真正要部署的构建物却是Customer-Service-Prod,又要如何验证这个软件最终会真正运行在生产环境中呢?>还有一些其他的挑战。首先,创建这些构建物比较耗时。其次,你需要在构建的时候知道存在哪些环境。你要如何处理敏感的配置数据?我可不想把生产环境的数据库密码提交到源代码中,但是如果在创建这些构建物时需要的话,通常这也是难以避免的。>一个更好的方法是只创建一个构建物,并将其配置单独管理。从形式上来说,这针对的可能是每个环境一个属性文件,或者是传入到安装过程中的一些参数。还有一个在应对大量微服务时比较流行的方法是,使用专用系统来提供配置,第11章会详细讨论这个话题。

配置漂移

当应用部署之后运行过程中,尤其是部署在多台服务器上之后,如果使用开发人员或者运维人员手工维护配置文件的方式,日积月累之后,会产生我们所谓的"配置飘移"问题,即由于应用以及依赖的组件的版本变更带来的配置差异,以及不同的团队或者人的多次不同时间点做的不同的修改会导致数据中心中每台机器上的相同的应用的配置在各台机器上或多或少都有细微的差别,而这往往是bug和重大故障隐藏之所。

10. 总结

在本文中,我们以一个测试和生产连接不同的数据库,配置不同的数据源(包括连接池)参数为例,介绍了如何将阿里云配置中心ACM与Spring Cloud一起使用,帮助你在微服务架构中简化你的环境配置管理。

原文链接

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容