zoukankan      html  css  js  c++  java
  • 携程阿波罗(Apollo)配置中心

    携程阿波罗(Apollo)

    https://www.cnblogs.com/xiaxiaolu/p/10025597.html

    img_1
    一、瞎扯点什么
    1.1 阿波罗
    ​ 阿波罗是希腊神话中的光明之神、文艺之神,同时也是罗马神话中的太阳神;他是光明之神,从不说谎,光明磊落,在其身上找不到黑暗,也被称作真理之神。他非常聪明,通晓世事,是预言之神。

    后世各种各样的项目都喜欢以阿波罗命名,比如著名的美国登月计划:阿波罗计划;

    既然携程以阿波罗(Apollo)命名项目,那我们我们接下来看看,携程阿波罗能给我们程序员带来怎样的光明(我希望这个光明是可以每天下午6点钟的太阳 哈哈);

    下面看看.net core和Apollo会碰撞出什么样的火花吧

    二、携程阿波罗(Apollo)
    2.1简单介绍
    在这之前,我们先看官方是怎么介绍的:

    Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。

    讲的很清楚,携程阿波罗(后面简称Apollo)是一个分布式的配置中心,就是管理配置程序配置地方;Apollo服务端基于Spring Boot和Spring Cloud开发(对的,就是微服务框架),打包后可以直接运行,不需要额外安装Tomcat等应用容器。

    Apollo有以下特点:

    统一管理不同环境、不同集群的配置
    配置修改实时生效(热发布)
    版本发布管理
    灰度发布
    权限管理、发布审核、操作审计
    客户端配置信息监控
    提供Java和.Net原生客户端
    提供开放平台API
    部署简单
    具体每一项展开是什么意思,我就不多说了,更多介绍请看Apollo配置中心介绍

    再多说一句,截止到这篇博客编写时间为止,Apollo在github已经有9300+个star了;

    并拥有众多的生产使用案例;

    2.2使用场景
    我们设想一下,我们微服务架构中,我们一个每一个服务都可能部署到5~10机器上,我们有很几十个各种各样的服务;比如某一天,我们机房因为网络问题,必须更换数据库服务器ip,业务接口ip等;如果人工去一台机一台机地改,哇,那就就头痛了。。。

    不止是微服务,做开发这么多年,经常因配置的问题引发生产环境的bug。有些年久的项目,几百个密密麻麻的配置项,经常容易搞混,有时好几个项目有好多同样的配置项,经常被配置问题,或者配置衍生的问题搞得奄奄一息;这时候或者选用一个配置管理中心,也是个不错的选择;

    有人说,我做了用了Jenkins或者什么做了自动化部署的,不是提交一下代码就可以了吗;确实,自动化部署环境确实也可以做到配置的“一处更改,所有引用起效”的效果;但是,镜像的打包失败,打包时间过长等问题,也需要考虑进来的;

    所以,综合来说,在配置人工管理困难的时候或者说成本较高的时候;使用配置中心是一个合理的选择;

    img

    三、Apollo的安装与配置
    3.1 环境
    windows10 64bit 专业版
    8G内存

    这次是我的本地环境,不是腾讯云了

    3.2 安装
    我也在学习中,演示的是本地测试环境的安装与配置,生产环境请参考分布式部署指南;

    我这里是普通方式的安装,docker方式请参考Apollo Quick Start Docker部署

    1、依次安装以下程序

    Java 1.8+

    Mysql 5.6.5+ (Apollo的表结构对timestamp使用了多个default声明,所以需要5.6.5以上版本。)

    GitBash (安装参考)

    下载apollo-build-scripts项目到本地

    2、创建数据库

    分别执行下面两个初始化的数据库sql:

    apolloconfigdb.sql

    apolloportaldb.sql

    执行完成我们得到:

    1542806085229

    3、修改配置文件

    修改刚刚下载项目apollo-build-scripts根目录下面的demo.sh

    !/bin/bash

    apollo config db info

    apollo_config_db_url=jdbc:mysql://139.199.196.67:3306/ApolloConfigDB?characterEncoding=utf8
    apollo_config_db_username=root
    apollo_config_db_password=password

    apollo portal db info

    apollo_portal_db_url=jdbc:mysql://139.199.196.67:3306/ApolloPortalDB?characterEncoding=utf8
    apollo_portal_db_username=root
    apollo_portal_db_password=password
    4、启动

    gitbash执行:

    ./demo.sh start
    静候片刻,看到以下表示启动成功(不一定一模一样):

    1543245209761

    注意检查数据库配置,确认无误后执行demo.sh,如果有报错多执行两次看看,因为我也有

    “Config service failed to start in 120 seconds! Please check ./service/apollo-service.log for more information.”

    这个报错,然后再次执行才启动成功的;

    接着如提示访问 http://127.0.0.1:8070

    1542792843089

    ok,我们登录看看,默认账号密码是:apollo/admin

    我们看到已经有一个SampleApp,作为配置参考了

    1542808265590

    1542808341712

    根据提示,我们再访问一下 8080 端口:

    我知道 Eureka 是java那边比较喜欢用的服务注册中心,是一个跟consul差不多一样的东西,我也不太熟,先放着;

    到这一步,Apollo我们已经安装成功了;接下来我们先参照SampleApp添加一个我们自己的app,为.net core程序的与她的亲密接触做准备;

    1542808483430

    四、创建/配置Apollo项目
    4.1 新建项目
    创建一个叫myDotnet的项目

    部门数据在ApolloPortalDB库ServerConfig表里配置

    1542809520034

    提交后我们看到如下提示,什么是Namespace??擦 需要补课;
    1542814456082

    4.2 什么是Namespace
    官方Apollo核心概念之Namespace已经讲得很清楚了。这里是我的理解,看看能不能概括一下:

    Apollo每一个项目下面都可以有多个Namespace,每一个Namespace都类似于我们开发中的一个配置文件。比如appsetting.json
    Namespace有两种权限(对客户端读取设置的权限):
    private:只能被所属的应用获取到,像放在当前运行程序目录下的配置;
    public:共有的配置,能被所有的引用获取到。像放在共享目录的配置;
    Namespace有三种类型(归类,给不同的归类设置不同的权限属性):

    私有类型:私有类型的Namespace具有上诉的private权限。
    公共类型:公共类型的Namespace具有上诉public权限,即任何应用都可获取;
    关联类型(继承类型):比如我们经常配置的timeout,公共配置timeout=60;,然后我本地可以配置的一个timeout=90;覆盖公共配置这种情景;
    4.2.2 示例
    如下图所示,有三个应用:应用A、应用B、应用C。

    应用A有两个私有类型的Namespace:application和NS-Private,以及一个关联类型的Namespace:NS-Public。
    应用B有一个私有类型的Namespace:application,以及一个公共类型的Namespace:NS-Public。
    应用C只有一个私有类型的Namespace:applicationNamespace例子
    2.2.1 应用A获取Apollo配置
    //application
    Config appConfig = ConfigService.getAppConfig();
    appConfig.getProperty("k1", null); // k1 = v11
    appConfig.getProperty("k2", null); // k2 = v21

    //NS-Private
    Config privateConfig = ConfigService.getConfig("NS-Private");
    privateConfig.getProperty("k1", null); // k1 = v3
    privateConfig.getProperty("k3", null); // k3 = v4

    //NS-Public,覆盖公共类型配置的情况,k4被覆盖
    Config publicConfig = ConfigService.getConfig("NS-Public");
    publicConfig.getProperty("k4", null); // k4 = v6 cover
    publicConfig.getProperty("k6", null); // k6 = v6
    publicConfig.getProperty("k7", null); // k7 = v7
    2.2.2 应用B获取Apollo配置
    //application
    Config appConfig = ConfigService.getAppConfig();
    appConfig.getProperty("k1", null); // k1 = v12
    appConfig.getProperty("k2", null); // k2 = null
    appConfig.getProperty("k3", null); // k3 = v32

    //NS-Private,由于没有NS-Private Namespace 所以获取到default value
    Config privateConfig = ConfigService.getConfig("NS-Private");
    privateConfig.getProperty("k1", "default value");

    //NS-Public
    Config publicConfig = ConfigService.getConfig("NS-Public");
    publicConfig.getProperty("k4", null); // k4 = v5
    publicConfig.getProperty("k6", null); // k6 = v6
    publicConfig.getProperty("k7", null); // k7 = v7
    2.2.3 应用C获取Apollo配置
    //application
    Config appConfig = ConfigService.getAppConfig();
    appConfig.getProperty("k1", null); // k1 = v12
    appConfig.getProperty("k2", null); // k2 = null
    appConfig.getProperty("k3", null); // k3 = v33

    //NS-Private,由于没有NS-Private Namespace 所以获取到default value
    Config privateConfig = ConfigService.getConfig("NS-Private");
    privateConfig.getProperty("k1", "default value");

    //NS-Public,公共类型的Namespace,任何项目都可以获取到
    Config publicConfig = ConfigService.getConfig("NS-Public");
    publicConfig.getProperty("k4", null); // k4 = v5
    publicConfig.getProperty("k6", null); // k6 = v6
    publicConfig.getProperty("k7", null); // k7 = v7
    仔细看完示例应该理解了,如果实在不了解,我们后面用示例自己去体会;

    4.3 添加Namespace和配置项
    我们在上面的myDotnet项目下面,分别添加一个Public类型的Namespace和一个Private类型的Namespace;

    其中:

    Hei.Public:Public类型,存放Mongodb连接,Redis连接等几乎每个程序都需要用到的公共配置;

    Hei.Private:Private类型,存放当前web应用程序需要使用的连接,比如title,keyword,description;

    1542850762853

    添加配置

    红圈的地方,有提示Public类型的Namespace能被任何应用读取

    添加完配置记得一定要点击发布,别问我怎么知道的。。。。

    1543283593089

    小tips:这些配置可以以文本形式,快速 批量添加的:

    1543283919947

    五、与Asp.Net Core的亲密接触(使用)
    5.1 简单使用
    1、引用nuget包:Com.Ctrip.Framework.Apollo.Configuration 

    1542852719125

    2、添加配置

    修改appsetting.json,添加Apollo节点配置:

    "apollo": {
    "AppId": "myDotnet", //这是我们上面添加的Apollo里面的Appid
    "MetaServer": "http://127.0.0.1:8080" //Apollo配置服务器地址,注意这里是8080,不是admin的8070
    }
    3、修改Program.cs,修改为:

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
    .ConfigureAppConfiguration((hostingContext, builder) =>
    {
    builder
    .AddApollo(builder.Build().GetSection("apollo"))
    .AddDefault() //默认的application Namespace
    .AddNamespace("TEST1.Hei.Public ") //public 类型的Namespace
    .AddNamespace("Hei.Private");//private 类型的Namespace
    })
    .UseStartup();
    非常简单,我们总共就修改了这3个地方,用起来也跟获取本地配置几乎无差;

    1543284034098

    来,我们看看运行结果:

    Public类型的:

    1543284400433

    Private类型的:

    1543284433973

    测试的时候可以随时在Apollo后台修改配置 发布后,刷新链接;可以看到,配置即时起效的。

    5.2 高级用法
    其实也不是什么高级用法。。。

    像什么回滚功能很容易理解;灰度发布,大家也可以试着用一下;

    1、关联类型的Namespace

    大家注意,我们之前一直使用的应用都是:myDotnet现在我们再添加一个netcore的应用,并且这个应用有一个Public的Namespace TEST2.Hei.Globa

    注意这里的MongoDB 跟上面的 myDotnet的配置的值不一样了

    1543287894670

    然后,我们给myDotnet 关联上这个 netcore的TEST2.Hei.Globa ,就等于myDotnet下面多了一个Namespace:

    1543287820353

    看到myDotnet下面多了一个Namespace:

    1543288136940

    修改下Program.cs

    1543288281731

    然后我们看看配置:

    MongoDB:还是以myDotnet的为准。

    1543287947865

    MysqlVersion:

    1543288318925

    2、监听配置的变化

    偷懒直接上代码:

    private static void OnChanged(object sender, ConfigChangeEventArgs changeEvent)
    {
    Console.WriteLine("Changes for namespace {0}", changeEvent.Namespace);
    foreach (string key in changeEvent.ChangedKeys)
    {
    ConfigChange change = changeEvent.GetChange(key);
    Console.WriteLine("Change - key: {0}, oldValue: {1}, newValue: {2}, changeType: {3}", change.PropertyName, change.OldValue, change.NewValue, change.ChangeType);
    }
    }

        static void Main(string[] args)
        {
            Config config = ConfigService.GetAppConfig(); //config instance is singleton for each namespace and is never null
            config.ConfigChanged += OnChanged;
    
            while (true)
            {
                Thread.Sleep(500);
                var timeout = config.GetProperty("timeout", "");
                Console.WriteLine(timeout);
            }
        }
    

    总结
    ​ 这篇文章的目的,是希望能给大家提供两点参考:Apollo是什么?Apollo可以做什么?

    达到这两点也就差不多了;至于Apollo提供的更多功能大家可以慢慢体会,我也在学习当中。至于Apollo的性能、稳定性这些,Apollo目前已经有不少公司落地使用了,是社区里面非常热的产品,说这些问题,应该都已解决。最后,我也是学习当中,有写的不对的地方,大家指正,欢迎交流。

    demo源码地址

    [参考]
    https://github.com/ctripcorp/apollo/wiki/

    https://www.cnblogs.com/edisonchou/p/9419379.html

    作者:乔达摩 (嘿~)

    出处:https://www.cnblogs.com/xiaxiaolu/p/10025597.html

  • 相关阅读:
    第一节:SpringMVC概述
    SpringMVC【目录】
    Windows 系统快速查看文件MD5
    (error) ERR wrong number of arguments for 'hmset' command
    hive使用遇到的问题 cannot recognize input
    Overleaf支持的部分中文字体预览
    Understanding and Improving Fast Adversarial Training
    Django2实战示例 第十三章 上线
    Django2实战示例 第十二章 创建API
    Django2实战示例 第十一章 渲染和缓存课程内容
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/10063256.html
Copyright © 2011-2022 走看看