H__D  

Apollo简介

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

  服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安装Tomcat等应用容器。

  Java客户端不依赖任何框架,能够运行于所有Java运行时环境,同时对Spring/Spring Boot环境也有较好的支持。

  .Net客户端不依赖任何框架,能够运行于所有.Net运行时环境。

  官方文档:https://www.apolloconfig.com/#/zh/README

Apollo设计

总体设计

  1、基础模型

  1. 用户在配置中心对配置进行修改并发布
  2. 配置中心通知Apollo客户端有配置更新
  3. Apollo客户端从配置中心拉取最新的配置、更新本地配置并通知到应用

  

  2、架构模块

  

  

  • Config Service提供配置的读取、推送等功能,服务对象是Apollo客户端

  • Admin Service提供配置的修改、发布等功能,服务对象是Apollo Portal(管理界面)

  • Eureka提供服务注册和发现,为了简单起见,目前Eureka在部署时和Config Service是在一个JVM进程中的

  • Config Service和Admin Service都是多实例、无状态部署,所以需要将自己注册到Eureka中并保持心跳

  • 在Eureka之上架了一层Meta Server用于封装Eureka的服务发现接口

  • Client通过域名访问Meta Server获取Config Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Client侧会做load balance、错误重试

  • Portal通过域名访问Meta Server获取Admin Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Portal侧会做load balance、错误重试

  • 为了简化部署,我们实际上会把Config Service、Eureka和Meta Server三个逻辑角色部署在同一个JVM进程中

服务端设计

  配置发布后的实时推送设计

  

  上图简要描述了配置发布的大致过程:

  1. 用户在Portal操作配置发布
  2. Portal调用Admin Service的接口操作发布
  3. Admin Service发布配置后,发送ReleaseMessage给各个Config Service
  4. Config Service收到ReleaseMessage后,通知对应的客户端

客户端设计

   

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

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

Apollo核心概念

  1. application (应用)

    这个很好理解,就是实际使用配置的应用,Apollo客户端在运行时需要知道当前应用是谁,从而可以去获取对应的配置

    关键字:appId

  2. environment (环境)

    配置对应的环境,Apollo客户端在运行时需要知道当前应用处于哪个环境,从而可以去获取应用的配置

    关键字:env

  3. cluster (集群)

    一个应用下不同实例的分组,比如典型的可以按照数据中心分,把上海机房的应用实例分为一个集群,把北京机房的应用实例分为另一个集群。

    关键字:cluster

  4. namespace (命名空间)

    一个应用下不同配置的分组,可以简单地把namespace类比为文件,不同类型的配置存放在不同的文件中,如数据库配置文件,RPC配置文件,应用自身的配置文件等

    关键字:namespaces

  关系:应用包含多个环境,环境包含多个集群,集群中包含多个命名空间

Apollo安装

  本例查用快速入门安装

  参考:https://www.apolloconfig.com/#/zh/deployment/quick-start

  1、下载一个Quick Start安装包,即可进行安装

  2、安装数据库,快速安装包sql目录中有sql文件直接安装

  3、修改demo.sh文件的数据库连接信息

  4、如果安装阿里云服务器上,需要外网访问,需要保证对应三个端口能访问,且需要修改注册到Eureka使用外网ip

  

   修改这一个地方即可,-Deureka.instance.ip-address=192.168.1.1(外网ip)

  5、启动服务

    启动命令:./demo.sh start

    停止命令:./demo.sh stop

  - http://127.0.0.1:8070  Apollo的 Portal 地址

  - http://127.0.0.1:8080 Eureka注册中心地址,同时也是 Apollo的 Config Service地址

  - http://127.0.0.1:8090 Apollo的 AdminService地址

Apollo使用

  1、访问地址:http://127.0.0.1:8070,默认账号密码:apollo/admin, 创建Apollo项目,并发布配置

  

  

  2、访问:http://127.0.0.1:8080 Eureka注册中心地址,同时也是 Apollo的 Config Service地址

   

   3、使用Java客户端连接

   创建Maven项目,引入依赖

<!-- apollo 依赖 -->
<dependency>
    <groupId>com.ctrip.framework.apollo</groupId>
    <artifactId>apollo-client</artifactId>
    <version>1.7.0</version>
</dependency>

   编写代码

 1 public class TestApollo {
 2 
 3     // 方法一 启动JVM参数:-Dapp.id=apollo-quickstart -Denv=DEV -Dapollo.cluster=default -Dapollo.meta=http://127.0.0.1:8080 
 4     // 方法二 System.setProperty("apollo.meta", "http://config-service-url");
 5     public static void main(String[] args) throws InterruptedException {
 6 
 7 
 8         Config config = ConfigService.getAppConfig(); //config instance is singleton for each namespace and is never null
 9         String someKey = "sms.enable";
10         String someDefaultValue = "------";
11         String value = config.getProperty(someKey, someDefaultValue);
12         System.out.println("value = " + value);
13 
14         while (true) {
15             value = config.getProperty(someKey, someDefaultValue);
16             System.out.printf("now: %s, sms.enable: %s%n", LocalDateTime.now().toString(), value);
17             Thread.sleep(3000L);
18         }
19     }
20 }

  启动运行,注意加入JVM参数-Apollo的连接信息

  

  

  可以在管理界面修改key的值,应用能够及时感应到变化,并使用最新值。俗称热发布

Apollo集成SpringBoot使用

  1、新建SpringBoot项目,加入Apollo依赖

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <modelVersion>4.0.0</modelVersion>
 6 
 7     <groupId>com.test</groupId>
 8     <artifactId>test-springboot-apollo</artifactId>
 9     <version>1.0-SNAPSHOT</version>
10 
11     <parent>
12         <groupId>org.springframework.boot</groupId>
13         <artifactId>spring-boot-starter-parent</artifactId>
14         <version>2.2.5.RELEASE</version>
15         <relativePath/> <!-- lookup parent from repository -->
16     </parent>
17 
18     <properties>
19         <maven.compiler.source>8</maven.compiler.source>
20         <maven.compiler.target>8</maven.compiler.target>
21     </properties>
22 
23     <dependencies>
24 
25         <dependency>
26             <groupId>org.springframework.boot</groupId>
27             <artifactId>spring-boot-starter-web</artifactId>
28         </dependency>
29 
30         <dependency>
31             <groupId>org.springframework.boot</groupId>
32             <artifactId>spring-boot-starter-test</artifactId>
33         </dependency>
34 
35         <!-- apollo 依赖 -->
36         <dependency>
37             <groupId>com.ctrip.framework.apollo</groupId>
38             <artifactId>apollo-client</artifactId>
39             <version>1.7.0</version>
40         </dependency>
41 
42     </dependencies>
43 
44 
45     <!-- SpringBoot打包插件,可以将代码打包成一个可执行的jar包 -->
46     <build>
47         <plugins>
48             <plugin>
49                 <groupId>org.springframework.boot</groupId>
50                 <artifactId>spring-boot-maven-plugin</artifactId>
51             </plugin>
52         </plugins>
53     </build>
54 
55 </project>
View Code

  2、编写配置文件application.properties文件

# AppId是应用的身份信息,是配置中心获取配置的一个重要信息。
app.id=apollo-quickstart
# apollo 缓存目录
apollo.cacheDir = ./apolloCacheDir
# 在应用启动阶段,向Spring容器注入被托管的application.properties文件的配置信息。
apollo.bootstrap.enabled = true
# 将Apollo配置加载提到初始化日志系统之前。这样日志配置可以托管到apollo
apollo.bootstrap.eagerLoad.enabled=true
# apollo 源信息
apollo.meta = http://127.0.0.1:8080/
# apollo 命名空间
apollo.bootstrap.namespaces = application

  3、编写启动类代码

 1 @SpringBootApplication
 2 public class Application implements CommandLineRunner {
 3 
 4     // apollo 支持 @Value注解
 5     // sms.enable = false
 6     @Value("${sms.enable}")
 7     private String value;
 8 
 9     // apollo 自己的json注解
10     // jsonArrayProperty = [{"someString":"hello","someInt":100},{"someString":"world!","someInt":200}]
11     @ApolloJsonValue("${jsonArrayProperty:[]}")
12     private List<Map<String, String>> jsonArrayProperty;
13 
14     // apollo 自己的json注解
15     // jsonBeanProperty = {"someString":"hello","someInt":100}
16     @ApolloJsonValue("${jsonBeanProperty:{}}")
17     private Map<String, String> jsonBeanProperty;
18 
19     public static void main(String[] args) {
20         SpringApplication.run(Application.class, args);
21     }
22 
23     @Override
24     public void run(String... args) throws Exception {
25         System.out.println("value = " + value);
26         System.out.println("jsonArrayProperty = " + jsonArrayProperty);
27         System.out.println("jsonBeanProperty = " + jsonBeanProperty);
28 
29 //        while (true) {
30 //            System.out.println("value = " + value);
31 //            Thread.sleep(3000L);
32 //        }
33     }
34 }

  注意:

    Apollo支持  @Value 注解,而且还有 apollo自带的注解 @ApolloJsonValue,可以解析json字符串

    缓存文件格式:{appId}+{cluster}+{namespace}.properties

  参考:

    教程:http://www.pbteach.com/java/java_05_03/20210527/582534840956485632.html

    博客:https://www.cnblogs.com/huanchupkblog/p/10509427.html

posted on 2021-11-12 15:05  H__D  阅读(2823)  评论(0编辑  收藏  举报