随着程序功能的日益复杂,程序的配置日益增多:各种功能的开关、参数的配置、服务器的地址……

对程序配置的期望值也越来越高:配置修改后实时生效,灰度发布,分环境、分集群管理配置,完善的权限、审核机制……

在这样的大环境下,传统的通过配置文件、数据库等方式已经越来越无法满足开发人员对配置管理的需求。

配置中心应运而生!

1、硬编码

没有什么配置不配置的,直接写在代码里面,比如使用常量类

优势 :对开发友好,开发清楚地知道代码需要用到什么配置

劣势 :涉及秘钥等敏感配置直接暴露给开发人员,不安全;如果想修改配置必须重新发版,比较麻烦

2、外部化配置文件

Spring项目经常会在resoures目录下放很多配置文件,各个环境对应不同的配置文件,通过SVN管理

优势 :配置文件外部化,支持多环境配置管理,修改配置只需重启服务,无需发版

劣势 :系统庞大时,配置文件很多,多人开发,配置格式不统一,维护麻烦;敏感配置不需要暴露给开发人员,降低风险,但开发经常要和运维沟通怎么修改配置,沟通不恰当容易引发生产事故;而且,如果应用部署在多台机器,对运维来说,修改配置也是非常头疼的事情(当然也可以引入NFS系统来解决一部分问题)

3、数据库

配置信息存储在数据库中,灵活修改

优势 :可以灵活管理配置,无需重启服务

劣势 :界面不友好,配置没有版本管理,一旦出现问题,回滚或定位问题都比较麻烦;此外,数据库必须要保证高可用,避免因此而造成生产故障

4、配置中心

微服务基础架构体系中的一个不可或缺的基础组件

优势 :集中化管理,敏感配置可控;多版本存储,方便追溯;界面友好,修改配置一键发布;即使面对多集群也能从容应对,十分淡定

劣势 :引入组件,增加系统风险;如果是中途切换成配置中心,也会增加研发接入成本;配置中心也需要保证高可用,否则容易造成大面积影响

以上几种管理配置文件的方式,我想都会有公司在用,不要因为配置中心有诸多优点,就盲目引进项目中,我觉得应该遵守以下两个原则:

  • 做人做事,要知道自己几斤几两
  • 释义:没深入研究过的技术,就不要随便拿到公司项目中来试水啦,恐怕到时候坑够你填的,要不然就是你有信心玩得转它。

  • 杀只鸡而已,你拿牛刀来做甚?
  • 释义:小团队小项目选择简单的配置管理方式就好了,要什么配置中心,纯属没事找事。

    总而言之,我们必须从实际出发,实事求是,选择适合自己的技术栈。

    当下我们的各个项目是独立的,各自的配置自行管理,缺少规范的权限、流程治理、以及不同版本的管理、回滚等。

    Apollo

    Apollo(阿波罗)是一款可靠的分布式配置管理中心,是由携程开源的一个项目,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。

    Apollo支持4个维度管理Key-Value格式的配置:

  • application (应用)
  • environment (环境)
  • cluster (集群)
  • namespace (命名空间)
  • GitHub地址

    GitHub - apolloconfig Start 26.1k

    Demo地址

    http://Apollo-demo.com

    ​ apollo/admin

    同时,Apollo基于开源模式开发,开源地址: https://github.com/ctripcorp/apollo

    下图简要描述了Apollo客户端的实现原理:

  • 客户端和服务端保持了一个长连接,从而能第一时间获得配置更新的推送。(通过Http Long Polling实现)
  • 客户端还会定时从Apollo配置中心服务端拉取应用的最新配置。
  • 这是一个fallback机制,为了防止推送机制失效导致配置不更新
  • 客户端定时拉取会上报本地版本,所以一般情况下,对于定时拉取的操作,服务端都会返回304 - Not Modified
  • 定时频率默认为每5分钟拉取一次,客户端也可以通过在运行时指定System Property: apollo.refreshInterval 来覆盖,单位为分钟。
  • 客户端从Apollo配置中心服务端获取到应用的最新配置后,会保存在内存中
  • 客户端会把从服务端获取到的配置在本地文件系统缓存一份
  • 在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置
  • 应用程序可以从Apollo客户端获取最新的配置、订阅配置更新通知
  • 如果Linux Server 1宕机时,client就只能读取本地磁盘上的config-cache了

  • Portal部署在生产环境的机房,通过它来直接管理FAT、UAT、PRO等环境的配置
  • Meta Server、Config Service和Admin Service在每个环境都单独部署,使用独立的数据库
  • Meta Server、Config Service和Admin Service在生产环境部署在两个机房,实现双活
  • Meta Server和Config Service部署在同一个JVM进程内,Admin Service部署在同一台服务器的另一个JVM进程内

    功能特性介绍

    要使用Apollo,第一步需要创建项目。

  • 打开apollo-portal主页
  • 点击“创建项目”
  • 输入项目信息
  • 部门:选择应用所在的部门
  • 应用AppId:用来标识应用身份的唯一id,格式为string,需要和客户端app.properties中配置的app.id对应
  • 应用名称:应用名,仅用于界面展示
  • 应用负责人:选择的人默认会成为该项目的管理员,具备项目权限管理、集群创建、Namespace创建等权限
  • 配置发布成功后,应用就可以通过Apollo客户端读取到配置了。

    Apollo目前提供Java客户端,具体信息请点击 Java客户端使用文档

    如果应用使用了其它语言,也可以通过直接访问Http接口获取配置,具体可以参考 其它语言客户端接入指南

    回滚已发布配置

    如果发现已发布的配置有问题,可以通过点击『回滚』按钮来将客户端读取到的配置回滚到上一个发布版本。

    这里的回滚机制类似于发布系统,发布系统中的回滚操作是将部署到机器上的安装包回滚到上一个部署的版本,但代码仓库中的代码是不会回滚的,从而开发可以在修复代码后重新发布。

    Apollo中的回滚也是类似的机制,点击回滚后是将发布到客户端的配置回滚到上一个已发布版本,也就是说客户端读取到的配置会恢复到上一个版本,但页面上编辑状态的配置是不会回滚的,从而开发可以在修复配置后重新发布。

    Nacos

    是阿里巴巴推出来的一个新开源项目,这是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。致力于发现、配置和管理微服务。 Nacos 提供了一组简单易用的特性集,实现动态服务发现、服务配置、服务元数据及流量管理。

    整体架构分为用户层、业务层、内核层和插件,用户层主要解决用户使用的易用性问题,业务层主要解决服务发现和配置管理的功能问题,内核层解决分布式系统一致性、存储、高可用等核心问题,插件解决扩展性问题。

    OpenAPI:暴露标准Rest风格HTTP接口,简单易用,方便多语言集成

    Console:易用控制台,做服务管理、配置管理等操作

    SDK:多语言 SDK,目前几乎支持所有主流编程语言

    Agent:Sidecar 模式运行,通过标准 DNS 协议与业务解耦

    CLI:命令行对产品进行轻量化管理,像 git 一样好用

    服务管理:实现服务 CRUD,域名 CRUD,服务健康状态检查,服务权重管理等功能

    配置管理:实现配置管 CRUD,版本管理,灰度管理,监听管理,推送轨迹,聚合数据等功能

    元数据管理:提供元数据 CURD 和打标能力,为实现上层流量和服务灰度非常关键

    插件机制:实现三个模块可分可合能力,实现扩展点 SPI 机制,用于扩展自己公司定制

    事件机制:实现异步化事件通知,SDK 数据变化异步通知等逻辑,是Nacos高性能的关键部分

    日志模块:管理日志分类,日志级别,日志可移植性(尤其避免冲突),日志格式,异常码+帮助文档

    回调机制:SDK 通知数据,通过统一的模式回调用户处理。接口和数据结构需要具备可扩展性

    寻址模式:解决 Server IP 直连,域名访问,Nameserver 寻址、广播等多种寻址模式,需要可扩展

    推送通道:解决 Server 与存储、Server 间、Server 与 SDK 间高效通信问题

    容量管理:管理每个租户,分组下的容量,防止存储被写爆,影响服务可用性

    流量管理:按照租户,分组等多个维度对请求频率,长链接个数,报文大小,请求流控进行控制

    缓存机制:容灾目录,本地缓存,Server 缓存机制,是 Nacos 高可用的关键

    启动模式:按照单机模式,配置模式,服务模式,DNS 模式模式,启动不同的模块

    一致性协议:解决不同数据,不同一致性要求情况下,不同一致性要求,是 Nacos 做到 AP 协议的关键

    存储模块:解决数据持久化、非持久化存储,解决数据分片问题

    Nameserver:解决 Namespace 到 ClusterID 的路由问题,解决用户环境与 Nacos 物理环境映射问题

    CMDB:解决元数据存储,与三方 CMDB 系统对接问题,解决应用,人,资源关系

    Metrics:暴露标准 Metrics 数据,方便与三方监控系统打通

    Trace:暴露标准 Trace,方便与 SLA 系统打通,日志白平化,推送轨迹等能力,并且可以和计量计费系统打通

    接入管理:相当于阿里云开通服务,分配身份、容量、权限过程

    用户管理:解决用户管理,登录,SSO 等问题

    权限管理:解决身份识别,访问控制,角色管理等问题

    审计系统:扩展接口方便与不同公司审计系统打通

    通知系统:核心数据变更,或者操作,方便通过SMS系统打通,通知到对应人数据变更

    功能特性介绍

    开发者或者运维人员往往需要在服务注册后,通过友好的界面来查看服务的注册情况,包括当前系统注册的所有服务和每个服务的详情。并在有权限控制的情况下,进行服务的一些配置的编辑操作。Nacos在这个版本开放的控制台的服务发现部分,主要就是提供用户一个基本的运维页面,能够查看、编辑当前注册的服务。

    服务列表管理

    服务列表帮助用户以统一的视图管理其所有的微服务以及服务健康状态。整体界面布局是左上角有服务的搜索框和搜索按钮,页面中央是服务列表的展示。服务列表主要展示服务名、集群数目、实例数目、健康实例数目和详情按钮五个栏目。

    在服务列表页面点击详情,可以看到服务的详情。可以查看服务、集群和实例的基本信息。

    服务流量权重支持及流量保护

    Nacos 为用户提供了流量权重控制的能力,同时开放了服务流量的阈值保护,以帮助用户更好的保护服务服务提供者集群不被意外打垮。如下图所以,可以点击实例的编辑按钮,修改实例的权重。如果想增加实例的流量,可以将权重调大,如果不想实例接收流量,则可以将权重设为0。

    服务元数据管理

    Nacos提供多个维度的服务元数据的暴露,帮助用户存储自定义的信息。这些信息都是以K-V的数据结构存储,在控制台上,会以k1=v1,k2=v2这样的格式展示。类似的,编辑元数据可以通过相同的格式进行。例如服务的元数据编辑,首先点击服务详情页右上角的“编辑服务”按钮,然后在元数据输入框输入:version=1.0,env=prod。

    点击确认,就可以在服务详情页面,看到服务的元数据已经更新了。

    服务优雅上下线

    Nacos还提供服务实例的上下线操作,在服务详情页面,可以点击实例的“上线”或者“下线”按钮,被下线的实例,将不会包含在健康的实例列表里。

    Nacos支持基于Namespace和Group的配置分组管理,以便用户更灵活的根据自己的需要按照环境或者应用、模块等分组管理微服务以及Spring的大量配置,在配置管理中主要提供了配置历史版本、回滚、订阅者查询等核心管理能力。

    多配置格式编辑器

    Nacos支持 YAML、Properties、TEXT、JSON、XML、HTML 等常见配置格式在线编辑、语法高亮、格式校验,帮助用户高效编辑的同时大幅降低格式错误带来的风险。

    Nacos支持配置标签的能力,帮助用户更好、更灵活的做到基于标签的配置分类及管理。同时支持用户对配置及其变更进行描述,方面多人或者跨团队协作管理配置。

    编辑DIFF

    Nacos支持编辑DIFF能力,帮助用户校验修改内容,降低改错带来的风险。

    Nacos提供示例代码能力,能够让新手快速使用客户端编程消费该配置,大幅降低新手使用门槛。

    监听者查询

    Nacos提供配置订阅者即监听者查询能力,同时提供客户端当前配置的MD5校验值,以便帮助用户更好的检查配置变更是否推送到 Client 端。

    配置的版本及一键回滚

    Nacos通过提供配置版本管理及其一键回滚能力,帮助用户改错配置的时候能够快速恢复,降低微服务系统在配置管理上的一定会遇到的可用性风险。

    命名空间管理

    Nacos 基于Namespace 帮助用户逻辑隔离多个命名空间,这可以帮助用户更好的管理测试、预发、生产等多环境服务和配置,让每个环境的同一个配置(如数据库数据源)可以定义不同的值。

    Nacos0.8 版本支持简单登录功能,默认用户名/密码为: nacos/nacos

    修改默认用户名/密码方法
  • 生成加密密码, 在 com.alibaba.nacos.console.utils.PasswordEncoderUtil.main 函数中,将 nacos 改成你要改成的密码,运行即可得到加密有算法。注意盐值是随机的,所以生成密码每次可能不一样,请不要担心。
  • public class PasswordEncoderUtil {
        public static void main(String[] args) {
            System.out.println(new BCryptPasswordEncoder().encode("nacos"));
    
  • 创建用户名或者密码的时候,用指定用户名密码即可。
  • INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);
    INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');
    
    关闭登录功能

    由于部分公司自己开发控制台,不希望被nacos的安全filter拦截。因此nacos支持定制关闭登录功能找到配置文件 ${nacoshome}/conf/application.properties, 替换以下内容即可。

    ## spring security config
    ### turn off security
    spring.security.enabled=false
    management.security=false
    security.basic.enabled=false
    nacos.security.ignore.urls=/**
    #nacos.security.ignore.urls=/,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/login,/v1/console/health,/v1/cs/**,/v1/ns/**,/v1/cmdb/**,/actuator/**
    

    默认会话保持时间为30分钟。30分钟后需要重新登录认证。 暂时不支持修改该默认时间。