zoukankan      html  css  js  c++  java
  • 分布式配置中心Apollo

    1,什么是分布式配置中心

    项目中配置文件比较繁杂,而且不同环境的不同配置修改相对频繁,每次发布都需要对应修改配置,如果配置出现错误,需要重新打包发布,时间成本较高,因此需要做统一的分布式注册中心,能做到自动更新配置文件信息,解决以上问题

    常用分布式配置中心框架

    Disconf(依赖于zookpeer)、Zookpeer()、diamond、携程(阿波罗)、Redis、xxl-conf

    Zookpeer保证配置文件信息实时更新 (事件通知)

    大型互联网公司自己内部都有自己独立分布式配置中心
    独立RPC、独立分布式各种解决方案
    注册中心解决 rpc服务治理
    分布式配置中心 解决分布式配置文件管理

    Apollo阿波罗简介

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

    Apollo阿波罗特点

    用户在Apollo修改完配置并发布后,客户端能实时(1秒)接收到最新的配置,并通知到应用程序。

    统一管理不同环境、不同集群的配置

     所有的配置发布都有版本概念,从而可以方便的支持配置的回滚。

    配置修改实时生效(热发布)

    用户在Apollo修改完配置并发布后,客户端能实时(1秒)接收到最新的配置,并通知到应用程序

    版本发布管理

    所有的配置发布都有版本概念,从而可以方便的支持配置的回滚

    灰度发布

    支持配置的灰度发布,比如点了发布后,只对部分应用实例生效,等观察一段时间没问题后再推给所有应用实例。

    权限管理、发布审核、操作审计

    应用和配置的管理都有完善的权限管理机制,对配置的管理还分为了编辑和发布两个环节,从而减少人为的错误。

    所有的操作都有审计日志,可以方便的追踪问题。

    客户端配置信息监控

    可以方便的看到配置在被哪些实例使用

    提供Java.Net原生客户端

    提供了Java.Net的原生客户端,方便应用集成

    支持Spring Placeholder, AnnotationSpring BootConfigurationProperties,方便应用使用(需要Spring 3.1.1+

    同时提供了Http接口,非Java.Net应用也可以方便的使用

    提供开放平台API

    Apollo自身提供了比较完善的统一配置管理界面,支持多环境、多数据中心配置管理、权限、流程治理等特性。

    不过Apollo出于通用性考虑,对配置的修改不会做过多限制,只要符合基本的格式就能够保存。

    在我们的调研中发现,对于有些使用方,它们的配置可能会有比较复杂的格式,如xml, json,需要对格式做校验。

    还有一些使用方如DAL,不仅有特定的格式,而且对输入的值也需要进行校验后方可保存,如检查数据库、用户名和密码是否匹配。

    对于这类应用,Apollo支持应用方通过开放接口在Apollo进行配置的修改和发布,并且具备完善的授权和权限控制

    部署简单

    配置中心作为基础服务,可用性要求非常高,这就要求Apollo对外部依赖尽可能地少

    目前唯一的外部依赖是MySQL,所以部署非常简单,只要安装好Java和MySQL就可以让Apollo跑起来

    Apollo还提供了打包脚本,一键就可以生成所有需要的安装包,并且支持自定义运行时参数

    Apollo整体架构原理

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

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

    2, Apollo 框架下载路径github

    https://github.com/ctripcorp/apollo

    里面有开发,设计思想问文档

    3,下载完成,解压

    appollo-master 相当于是源码,apollo-build-scripts-master相当于将好几个服务集成到一块,用shell 脚本demo.sh 一键启动

    4,将apollo-build-scripts-master 文件夹发送到虚拟机192.168.178.110 /usr/local 的路径下、

    5,打开apollo-build-scripts-master/sql 下两个sql 文件,并且将他们刷入到数据库,注意mysql 数据库版本是要5.7 以上

    6,配置demo.sh

    #!/bin/bash
    
    # apollo config db info
    apollo_config_db_url=jdbc:mysql://192.168.178.110:3306/ApolloConfigDB?characterEncoding=utf8
    apollo_config_db_username=root
    apollo_config_db_password=12345678
    
    # apollo portal db info
    apollo_portal_db_url=jdbc:mysql://192.168.178.110:3306/ApolloPortalDB?characterEncoding=utf8
    apollo_portal_db_username=root
    apollo_portal_db_password=12345678
    
    # =============== Please do not modify the following content =============== #
    
    if [ "$(uname)" == "Darwin" ]; then
        windows="0"
    elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
        windows="0"
    elif [ "$(expr substr $(uname -s) 1 5)" == "MINGW" ]; then
        windows="1"
    else
        windows="0"
    fi
    
    # meta server url
    config_server_url=http://192.168.178.110:8080
    admin_server_url=http://192.168.178.110:8090
    eureka_service_url=$config_server_url/eureka/
    portal_url=http://192.168.178.110:8070

    需要修改的点,已经标注出来了,

    数据库,本来是安装在了windows 系统上,也设置了可以远程登陆,但是启动的适合都连不上,所以直接在本机,安装了linux版本的数据库

    配置完成,开始启动

    进入到//usr/local/apollo-build-scripts-master 输入命令:

    ./demo.sh start

    出现以下界面,则配置成功:

    4,url 路径所代表的意思:

    从上图中,可以看出几个服务:

    Config service:http://192.168.178.110:8080    给应用端调用

    Portal service:http://192.168.178.110:8070

    Admin Service:为了给Portal service 调用

    Config service: 就是Eureka 注册中心,将服务注册到Eureka 上进行管理

    Portal service:用户名apollo 密码admin  进入到了分布式配置中心web 界面

    进入之后:

    5,springboot 项目集成apollo

     创建Java workding set,名称分布式配置中心,在里面创建springboot 项目,导入maven 

    <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.1.RELEASE</version>
            <relativePath /> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <spring-cloud.version>Finchley.RC1</spring-cloud.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <!-- <exclusions> <exclusion> <groupId>com.fasterxml.jackson.core</groupId> 
                    <artifactId>jackson-databind</artifactId> </exclusion> </exclusions> -->
            </dependency>
    
            <!-- apollo 携程apollo配置中心框架 -->
            <dependency>
                <groupId>com.ctrip.framework.apollo</groupId>
                <artifactId>apollo-client</artifactId>
                <version>1.0.0</version>
            </dependency>
            <dependency>
                <groupId>com.ctrip.framework.apollo</groupId>
                <artifactId>apollo-core</artifactId>
                <version>1.0.0</version>
            </dependency>
    
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.3</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.1</version>
                    <executions>
                        <execution>
                            <id>copy-conf</id>
                            <phase>package</phase>
                            <goals>
                                <goal>copy-resources</goal>
                            </goals>
                            <configuration>
                                <encoding>UTF-8</encoding>
                                <outputDirectory>${project.build.directory}/ext/conf</outputDirectory>
                                <resources>
                                    <resource>
                                        <directory>ext/conf</directory>
                                        <includes>
                                            <include>logback.xml</include>
                                        </includes>
                                        <filtering>true</filtering>
                                    </resource>
                                </resources>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.jacoco</groupId>
                    <artifactId>jacoco-maven-plugin</artifactId>
                    <version>0.7.5.201505241946</version>
                    <executions>
                        <execution>
                            <id>default-prepare-agent</id>
                            <goals>
                                <goal>prepare-agent</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>default-prepare-agent-integration</id>
                            <goals>
                                <goal>prepare-agent-integration</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>com.spotify</groupId>
                    <artifactId>docker-maven-plugin</artifactId>
                    <version>0.4.3</version>
                    <configuration>
                        <imageName>hy_uav_gateway</imageName>
                        <dockerDirectory>src/main/docker</dockerDirectory>
                        <resources>
                            <resource>
                                <targetPath>/</targetPath>
                                <directory>${project.build.directory}</directory>
                                <include>${project.build.finalName}.jar</include>
                                <include>ext/conf/logback.xml</include>
                            </resource>
                        </resources>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
        <repositories>
            <repository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>https://repo.spring.io/milestone</url>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
        </repositories>

    6,将阿波罗build 到本地仓库

    因为以下这两个包是需要引用Apollo 的包的,也就是之前Apollo-master 的源码的包

     <!-- apollo 携程apollo配置中心框架 -->
            <dependency>
                <groupId>com.ctrip.framework.apollo</groupId>
                <artifactId>apollo-client</artifactId>
                <version>1.0.0</version>
            </dependency>
            <dependency>
                <groupId>com.ctrip.framework.apollo</groupId>
                <artifactId>apollo-core</artifactId>
                <version>1.0.0</version>
            </dependency>

    2中方式可以将源码打入本地maven 仓库,第一种,是将源码导入到eclipse中,利用mvn -install 下

    第二种方式就是在Apollo-master/scripts 下的build.bat 文件双击,就会自动将包build 

    build 完成之后,maven 仓库就生成了Apollo的包

    7,现在在将springboot 项目update ,就可以引用了。

    8,创建 apollo-env.properties 去连接apollo 分布式配置中心

    local.meta=http://192.168.178.110:8080
    dev.meta=http://192.168.178.110:8080
    fat.meta=${fat_meta}
    uat.meta=${uat_meta}
    lpt.meta=${lpt_meta}
    pro.meta=${pro_meta}
    

    9,在resources 文件夹下,建立appid ,一个appid,代表一个应用

    10,因为项目有好几种环境,有开发,测试,预生产,生产等,怎么区分apollo 分布式配置中心连的是那种环境呢

    修改/opt/settings/server.properties(Mac/Linux)或C:optsettingsserver.properties(Windows)文件,设置env为DEV:
    
    env=DEV

    11,springboot 测试,能否获得配置中心的值

    @RestController
    public class IndexController {
    
        @Value("${projectName:default}")
        private String projectName;
    
        @Value("${projectLeader:default}")
        private String projectLeader;
    
        @RequestMapping("/read")
        public String read() {
            return projectName + "===" + projectLeader;
        }
    
    }

    启动类:

    @Configuration
    @EnableApolloConfig
    @SpringBootApplication
    @EnableAutoConfiguration
    public class App {
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    
    }

    12,项目启动之后,还需要在Apollo 配置中心上把projectName,projectLeader 这两个key的value 添加,apllo 如何知道是哪个项目,就是根据appid

    创建项目:

    在项目上添加配置的值,支持回滚

    13,测试成功

  • 相关阅读:
    python从入门到实践-5章if语句
    HiveQL:文件格式和压缩方法
    HiveQL:调优
    HiveQL:模式设计
    HiveQL:视图
    (转)配置文件.bash_profile和.bashrc的区别
    Hive-学习总结(二)
    Hive-学习总结
    MYSQL-表类型(存储引擎)的选择
    MYSQL-常用函数
  • 原文地址:https://www.cnblogs.com/pickKnow/p/11351017.html
Copyright © 2011-2022 走看看