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

配置的环境属性

在系统持续交付的过程中,运行环境的多样性和复杂性增加了配置管理工作的负担。这一点在Eugen Paraschiv的博文Configuration Must Be Environment Specific里有简单的阐述。

环境配置的差异导致了应用的构建物(artifact)在各个环境不能保持一致,而且有时候Docker无法轻易达成只搭建一次即可在所有环境运行的效果。以下列举一些简单的例子来帮助您理解:

  • 在开发环境中logLevel应设置为DEBUG,在预发环境中为INFO,在生产环境中为WARNING。
  • 在开发环境中使用4核8G的机器运行数据库,而在生产中用32核96G的机器运行数据库。
  • 在日常环境执行线程池的最大线程数应该设置为15,而生产环境上该值应该大一些,默认设为150。
  • 在线上环境中,中心机房内应用数据源需要连接A库,而深圳机房,应用应该就近连接B库。
  • 新的特性仅在线上的杭州单元开放,其他单元环境暂缓。

下文中,简要介绍了使用阿里ACM配置管理产品在Spring Cloud中替代Spring Cloud Config的方法,帮助您理解基于ACM简化微服务环境配置管理的方案。此外,下文还将简要比较说明ACM与Spring Cloud Config方案的优劣。

场景故事

为帮助您理解需求和场景,我们一般会以用户故事(User Story)的方式预设一个简单的场景,以此来做阐释和交流。下面是一张早期的布道图。

以Movie Service为例,假设需要从关系数据库MySQL(RDS) 检索所有电影信息列表,但是只有生产库需要顶配的机器,测试、预发和生产环境需要使用不同的数据库,因此应用需要在不同的环境下具备不同的数据源配置、连接池配置、数据库安全配置等。

下图介绍了如何基于阿里云ACM的Namespace映射不同环境,为Movie Service在不同运行环境下设置不同的数据源配置。

创建微服务Movie Service

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

    movie service的业务逻辑很简单——列出MySQL(RDS)中所有的movie:

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

    工程结构
  • 引入JPA、MySQL、连接池HikariCP以及WEB依赖

    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <scope>runtime</scope>
    </dependency>
    <dependency>
       <groupId>com.zaxxer</groupId>
       <artifactId>HikariCP</artifactId>
       <version>2.7.6</version>
    </dependency>
  • 创建MySQL(RDS) 数据库及用户

    mysql> create database db_example; -- Create the new database
    mysql> create user 'springuser'@'localhost' identified by 'ThePassword'; -- Creates the user
    mysql> 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;
     import org.springframework.web.bind.annotation.RequestMapping;
     import org.springframework.web.bind.annotation.ResponseBody;
     import org.springframework.web.bind.annotation.RestController;
     import com.alibaba.demo.microsvc.dao.MovieRepository;
     import com.alibaba.demo.microsvc.model.Movie;
     @RestController
     public class MovieController {
         @Autowired
         MovieRepository movieRepository;
         @RequestMapping("/list-movies")
         public @ResponseBody Iterable<Movie> listMovies() {
               return movieRepository.findAll();
         }    
    }

在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

Movie Service与配置中心ACM集成

现在我们将集成Movie Service与ACM,以便从ACM中获取对应环境的配置。关于如何在Spring Cloud中使用ACM,请参见Spring Cloud ACM

  • 为movie service引入ACM依赖

    <dependency>
       <groupId>com.alibaba.cloud</groupId>
       <artifactId>spring-cloud-starter-acm</artifactId>
       <version>1.0.1</version>
    </dependency>
  • 在application.properties配置ACM连接信息、namespace、accessKey、secretKey等信息

    spring.application.name=movie-service
    spring.application.group=com.alibaba.cloud.acm
    alibaba.acm.endpoint=acm.aliyun.com
    alibaba.acm.namespace=<your_namespace_id>
    alibaba.acm.accessKey=<your_ak>        
    alibaba.acm.secretKey=<your_sk>
命名空间详情
说明

您可以在ACM的“命名空间详情”或者“配置的示例代码”里找到您的namespace_id、accessKey、secretKey等信息。

在浏览器里访问Movie Service

在浏览器里访问 Movie Service

查看ACM配置推送刷新信息

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

查看 ACM 配置推送刷新信息

也可以在 ACM 控制台上查看配置的推送轨迹、配置版本等信息,详情请参见查看历史版本和回滚配置以及查询推送轨迹

ACM与Spring Cloud Config的简单对比

对比项 Spring Cloud Config 阿里云ACM
Spring Cloud无缝集成 支持 支持
源码分发方式 开源 即将开源
收费模式 免费 免费
大规模(超10万配置)生产验证 无公开的大规模生产验证案例 阿里巴巴数据中心生产环境超百万级配置,每天超亿级配置变更推送,双11等严苛场景验证。
配置管控UI控制台 无控制台,依赖IDE、GIT等第三方工具 专业的配置管理UI控制台
多语言支持 主要支持Java生态,无其他语言的原生客户端 支持nodejs、c++等原生多语言客户端。
多机房、同城双活、异地多活、多可用区等架构 依赖GIT、ZooKeeper等能力支持,官方无明确说明 支持
配置变更推送 依赖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级(存储,服务器缓存) 3级,另有客户端本地容灾能力

工程下载

本文的样例工程可以从 movie-service.tar.gz 下载。

该工程在以下版本环境测试通过:

  • Spring Cloud Edgware.RELEASE
  • Spring Boot 1.5.9.RELEASE
  • HikariCP 2.7.6
  • MySQL 5.7.11
  • ACM 4.2.0
  • ACM Spring Cloud SDK 1.0.1
说明 在本地运行该工程前,请务必在application.properties里设置您自己的ACM accessKey和secretKey。