微服务 分布式配置中心Apollo详解
- 1. 配置中心概述
- 1.1 配置中心简介
- 1.2 配置中心特点
- 1.3 配置中心对比
- 2. Apollo概述
- 2.1 Apollo简介
- 2.2 Apollo特点
- 3. Apollo设计实现
- 3.1 基础模型
- 3.2 架构设计
- 3.3 Why Eureka
- 3.4 模块说明
- 4. Apollo安装部署
- 4.1 部署说明
- 4.2 环境准备
- 3.3 下载安装包
- 4.4 创建数据库
- 4.5 修改配置文件
- 4.6 启动应用程序
- 4.7 使用配置中心
- 5. Apollo集成SpringBoot
- 5.1 使用说明
- 5.2 开发验证
- 5.2 集成问题
- 5.3 灰度测试
- 5.4 热更新问题
- 6. Apollo问题总结
- 6.1 Apollo FAQ
- 6.2 Apollo性能测试报告
1. 配置中心概述
1.1 配置中心简介
配置就是应用程序在启动和运行的时候往往需要读取一些配置信息,配置基本上伴随着应用程序的整个生命周期,比如:数据库连接参数、启动参数等。常见的配置properties,yml,xml等。
先说为什么需要配置中心,传统的配置有什么问题?
没有配置也可以在代码写死,为什么需要配置文件,其实这个问题就是配置文件的优点了,比如,统一管理配置信息,灵活调整,方便扩展。
分布式微服务的出现,导致不同模块领域划分为独立应用,每个独立应用为了保持高可用搭建为集群部署,所以一个产品线对应几十个应用,每个应用对应上百台机器,按照传统方式配置文件,那每次修改配置都要修改上百台应用的配置,可维护性,扩展性极低。分布式配置中心是独立于每一个应用服务的单独组件,统一对外提供配置服务,便于维护扩展管理。
总结一句话:配置中心就是一种统一管理各种应用配置的基础服务组件。
1.2 配置中心特点
1.配置是独立于程序的只读变量
配置首先是独立于程序的,同一份程序在不同的配置下会有不同的行为。其次,配置对于程序是只读的,程序通过读取配置来改变自己的行为,但是程序不应该去改变配置。
2.配置伴随应用的整个生命周期
配置贯穿于应用的整个生命周期,应用在启动时通过读取配置来初始化,在运行时根据配置调整行为。比如:启动时需要读取服务的端口号、系统在运行过程中需要读取定时策略执行定时任务等。
3.配置可以有多种加载方式
常见的有程序内部硬编码,配置文件,环境变量,启动参数,基于数据库等。
4 配置需要治理
权限控制:由于配置能改变程序的行为,不正确的配置甚至能引起灾难,所以对配置的修改必须有比较完善的权限控制。不同环境、集群配置管理:同一份程序在不同的环境(开发,测试,生产)、不同的集群(如不同的数据中心)经常需要有不同的配置,所以需要有完善的环境、集群配置管理。
1.3 配置中心对比
总的来看,Apollo和Nacos相对于Spring Cloud Config的生态支持更广,在配置管理流程上做的更好。Apollo相对于Nacos在配置管理做的更加全面,Nacos则使用起来相对比较简洁,在对性能要求比较高的大规模场景更适合。但对于一个开源项目的选型,项目上的人力投入(迭代进度、文档的完整性)、社区的活跃度(issue的数量和解决速度、Contributor数量、社群的交流频次等),这些因素也比较关键,考虑到Nacos开源时间不长和社区活跃度,所以从目前来看Apollo应该是最合适的配置中心选型。
2. Apollo概述
2.1 Apollo简介
Apollo(阿波罗)是一款可靠的分布式配置管理中心,诞生于携程框架研发部,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
服务端基于Spring Boot和Spring Cloud开发,打包后可以直接运行,不需要额外安装Tomcat等应用容器。
Java客户端不依赖任何框架,能够运行于所有Java运行时环境,同时对Spring/Spring Boot环境也有较好的支持。
.Net客户端不依赖任何框架,能够运行于所有.Net运行时环境。
更多产品介绍参见Apollo配置中心介绍。
本地快速部署请参见Quick Start
演示环境(Demo):
http://81.68.181.139
账号/密码:apollo/admin
apollo gitee :https://gitee.com/apolloconfig
apollo github:https://github.com/apolloconfig
apollo 官方地址:https://www.apolloconfig.com/#/zh/README
2.2 Apollo特点
1.统一管理不同环境、不同集群的配置
- Apollo提供了一个统一界面集中式管理不同环境(environment)、不同集群(cluster)、不同命名空间(namespace)的配置。
- 同一份代码部署在不同的集群,可以有不同的配置,比如zk的地址等
- 通过命名空间(namespace)可以很方便的支持多个不同应用共享同一份配置,同时还允许应用对共享的配置进行覆盖
- 配置界面支持多语言(中文,English)
2.配置修改实时生效(热发布)
用户在Apollo修改完配置并发布后,客户端能实时(1秒)接收到最新的配置,并通知到应用程序。
3.版本发布管理
所有的配置发布都有版本概念,从而可以方便的支持配置的回滚。
4.灰度发布
支持配置的灰度发布,比如点了发布后,只对部分应用实例生效,等观察一段时间没问题后再推给所有应用实例。
5.权限管理、发布审核、操作审计
- 应用和配置的管理都有完善的权限管理机制,对配置的管理还分为了编辑和发布两个环节,从而减少人为的错误。
- 所有的操作都有审计日志,可以方便的追踪问题。
6.客户端配置信息监控
可以方便的看到配置在被哪些实例使用
7.提供Java和.Net原生客户端
- 提供了Java和.Net的原生客户端,方便应用集成
- 支持Spring Placeholder,Annotation和Spring Boot的ConfigurationProperties,方便应用使用(需要Spring 3.1.1+)
- 同时提供了Http接口,非Java和.Net应用也可以方便的使用
8.提供开放平台API
- Apollo自身提供了比较完善的统一配置管理界面,支持多环境、多数据中心配置管理、权限、流程治理等特性。
- 不过Apollo出于通用性考虑,对配置的修改不会做过多限制,只要符合基本的格式就能够保存。
- 在我们的调研中发现,对于有些使用方,它们的配置可能会有比较复杂的格式,如xml, json,需要对格式做校验。
- 还有一些使用方如DAL,不仅有特定的格式,而且对输入的值也需要进行校验后方可保存,如检查数据库、用户名和密码是否匹配。
- 对于这类应用,Apollo支持应用方通过开放接口在Apollo进行配置的修改和发布,并且具备完善的授权和权限控制
8.部署简单
- 配置中心作为基础服务,可用性要求非常高,这就要求Apollo对外部依赖尽可能地少
- 目前唯一的外部依赖是MySQL,所以部署非常简单,只要安装好Java和MySQL就可以让Apollo跑起来
- Apollo还提供了打包脚本,一键就可以生成所有需要的安装包,并且支持自定义运行时参数
3. Apollo设计实现
3.1 基础模型
如下即是Apollo的基础模型:
1.用户在配置中心对配置进行修改并发布
2.配置中心通知Apollo客户端有配置更新
3.Apollo客户端从配置中心拉取最新的配置、更新本地配置并通知到应用
3.2 架构设计
下图是Apollo的作者宋顺给出的架构图概览,详细说明可以参考Apollo配置中心架构剖析。
可能从架构图并不能很清晰的明白整个架构设计,业务流转,下边给出一些说明结合上图理解相对容易些。
1.Config Service提供配置的读取、推送等功能,服务对象是Apollo客户端。
2.Admin Service提供配置的修改、发布等功能,服务对象是Apollo Portal(管理界面)。
3.Config Service和Admin Service都是多实例、无状态部署,所以需要将自己注册到Eureka中并保持心跳。
4.在Eureka之上我们架了一层Meta Server用于封装Eureka的服务发现接口。
5.Client通过域名访问Meta Server获取Config Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Client侧会做load balance、错误重试。
6.Portal通过域名访问Meta Server获取Admin Service服务列表(IP+Port),而后直接通过IP+Port访问服务,同时在Portal侧会做load balance、错误重试。
7.为了简化部署,我们实际上会把Config Service、Eureka和Meta Server三个逻辑角色部署在同一个JVM进程中。
3.3 Why Eureka
关于为什么采用eureka作者给了三点原因
1.它提供了完整的Service Registry和Service Discovery实现。
2.和SpringCloud无缝集成。
3.Open Source,对也就是开源。
3.4 模块说明
各个模块说明详见官网说明。
4. Apollo安装部署
4.1 部署说明
为了让大家更快的上手了解Apollo配置中心,我们这里准备了一个Quick Start,能够在几分钟内在本地环境部署、启动Apollo配置中心。
考虑到Docker的便捷性,我们还提供了Quick Start的Docker版本,如果你对Docker比较熟悉的话,可以参考Apollo Quick Start Docker部署通过Docker快速部署Apollo。
不过这里需要注意的是,Quick Start只针对本地测试使用,如果要部署到生产环境,还请另行参考分布式部署指南。
4.2 环境准备
1.Java环境
Apollo服务端:1.8+
Apollo客户端:1.8+
在配置好后,可以通过如下命令检查:
java -version
正常输出:
java version "1.8.0_74"
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)
注意事项:
如需运行在 Java 1.7 运行时环境,请使用 1.x 版本的 apollo 客户端,如 1.9.1
Windows用户请确保JAVA_HOME环境变量已经设置。
2.MySQL
版本要求:5.6.5+
Apollo的表结构对timestamp使用了多个default声明,所以需要5.6.5以上版本。
连接上MySQL后,可以通过如下命令检查:
SHOW VARIABLES WHERE Variable_name = 'version';
正常输出
Variable_name | Value |
---|---|
version | 5.7.11 |
3.3 下载安装包
我们准备好了一个Quick Start安装包,大家只需要下载到本地,就可以直接使用,免去了编译、打包过程。
安装包共50M,如果访问github网速不给力的话,可以从百度网盘下载。
从GitHub下载
checkout或下载apollo-build-scripts项目
由于Quick Start项目比较大,所以放在了另外的repository,请注意项目地址
https://github.com/nobodyiam/apollo-build-scripts
从百度网盘下载
通过网盘链接下载,提取码: 9wwe
下载到本地后,在本地解压apollo-quick-start.zip
为啥安装包要58M这么大?
因为这是一个可以自启动的jar包,里面包含了所有依赖jar包以及一个内置的tomcat容器
注意如果是源码需要手动打包。
4.4 创建数据库
找到解压apollo-quick-start.zip后的文件下的sql文件夹,包含两个sql脚本apolloconfigdb.sql 与 apolloportaldb.sql。
Apollo服务端共需要两个数据库:ApolloPortalDB和ApolloConfigDB,我们把数据库、表的创建和样例数据都分别准备了sql文件,只需要导入数据库即可。
注意:如果你本地已经创建过Apollo数据库,请注意备份数据。我们准备的sql文件会清空Apollo相关的表。
通过Navicat客户端直接导入这两个sql文件即可,选择数据库右键,运行sql文件,选择sql文件执行,然后刷新,可以看到两个新的数据库apolloconfigdb与apolloportaldb。
或者通过命令执行也可,创建ApolloPortalDB与ApolloConfigDB,并且验证。
source /your_local_path/sql/apolloportaldb.sql
select `Id`, `AppId`, `Name` from ApolloPortalDB.App;
source /your_local_path/sql/apolloconfigdb.sql
select `NamespaceId`, `Key`, `Value`, `Comment` from ApolloConfigDB.Item;
4.5 修改配置文件
Apollo服务端需要知道如何连接到你前面创建的数据库,所以需要编辑demo.sh,修改ApolloPortalDB和ApolloConfigDB相关的数据库连接串信息。
注意:填入的用户需要具备对ApolloPortalDB和ApolloConfigDB数据的读写权限。
# apollo config db info
apollo_config_db_url="jdbc:mysql://localhost:3306/ApolloConfigDB?characterEncoding=utf8&serverTimezone=Asia/Shanghai"
apollo_config_db_username=${APOLLO_CONFIG_DB_USERNAME:-root}
apollo_config_db_password=${APOLLO_CONFIG_DB_PASSWORD:-123456}
# apollo portal db info
apollo_portal_db_url="jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8&serverTimezone=Asia/Shanghai"
apollo_portal_db_username=${APOLLO_PORTAL_DB_USERNAME:-root}
apollo_portal_db_password=${APOLLO_PORTAL_DB_PASSWORD:-123456}
4.6 启动应用程序
启动应用程序的时候需要注意,如果是Windows环境是不能使用cmd窗口执行demo.sh脚本的,一般开发安装的都有gitbash,可以通过Git Bash Here打开命令窗口执行启动命令,如果没有安装gitbash则通过Java -jar的方式单独启动。
Quick Start脚本会在本地启动3个服务,分别使用8070, 8080, 8090端口,请确保这3个端口当前没有被使用。
1.首先检查端口是否占用
在Linux/Mac下,可以通过如下命令检查:
lsof -i:8080
windows端口查看端口占用情况
输入【netstat -ano】命令,回车,就可看到Windows系统当前所有端口的占用情况
输入【netstat -aon|findstr “端口号”】命令,回车,就可以看到指定端口的占用情况
输入【tasklist|findstr “被占用端口对应的 PID”】命令,就可以查看是哪个进程或者程序占用了相应的端口。
输入【taskkill /t /f /pid pid号】 命令,结束端口占用的进程。
netstat -ano
netstat -aon|findstr "8080"
tasklist|findstr "151520"
taskkill /t /f /pid 151520
2.执行启动脚本
Windows打开gitbash,Linux打开命令窗口。执行demo.sh脚本。
./demo.sh start
当看到如下输出,则说明启动成功
Think@LAPTOP-DIDC0OGA MINGW64 /c/software/apollo-quick-start-2.0.1
$ ./demo.sh start
Windows new JAVA_HOME is: /c/software/Java/JDK18~1.0_1
==== starting service ====
Service logging file is ./service/apollo-service.log
Started [1589]
Waiting for config service startup...
Config service started. You may visit http://localhost:8080 for service status now!
Waiting for admin service startup.
Admin service started
==== starting portal ====
Portal logging file is ./portal/apollo-portal.log
Started [1634]
Waiting for portal startup...
Portal started. You can visit http://localhost:8070 now!
4.7 使用配置中心
1.查看样例配置
打开配置中心页面:http://localhost:8070
Quick Start集成了Spring Security简单认证,更多信息可以参考Portal 实现用户登录功能
2.登录客户端
输入用户名apollo,密码admin后登录
3.首页案例
点击SampleApp进入配置界面,可以看到当前有一个配置timeout=100 配置界面
如果提示系统出错,请重试或联系系统负责人,请稍后几秒钟重试一下,因为通过Eureka注册的服务有一个刷新的延时。
4.可以通过配置中心页面进行简单的操作
创建新的应用,简单配置,开启密匙管理。
5.运行客户端程序进行验证
我们准备了一个简单的Demo客户端来演示从Apollo配置中心获取配置。程序很简单,就是用户输入一个key的名字,程序会输出这个key对应的值。如果没找到这个key,则输出undefined。同时,客户端还会监听配置变化事件,一旦有变化就会输出变化的配置信息。
运行./demo.sh client启动Demo客户端,忽略前面的调试信息,可以看到如下提示:
Apollo Config Demo. Please input key to get the value. Input quit to exit.
>timeout
> [SimpleApolloConfigDemo] Loading key : timeout with value: 100
5. Apollo集成SpringBoot
5.1 使用说明
详情参考 Java客户端使用指南:https://www.apolloconfig.com/#/zh/usage/java-sdk-user-guide
5.2 开发验证
1.项目结构
│ apollo-platform
├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─zrj
│ │ │ └─apollo
│ │ │ └─platform
│ │ │ │ ApolloPlatformApplication.java
│ │ │ │
│ │ │ ├─config
│ │ │ │ ApolloConfig.java
│ │ │ │ ApolloConfigBean.java
│ │ │ │ ApolloConfigListener.java
│ │ │ │
│ │ │ └─controller
│ │ │ ApolloController.java
│ │ │
│ │ └─resources
│ │ application.properties
│ │
└─pom.xml
2.maven依赖
<!--apollo-client-config-data已经依赖apollo-client, 所以只需要添加这一个依赖即可, 无需再添加apollo-client的依赖-->
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client-config-data</artifactId>
<version>2.0.1</version>
</dependency>
2.配置文件
application.properties
# 端口
server.port=8088
# apollo config
app.id=apollo-platform
apollo.meta=127.0.0.1:8080
apollo.access-key.secret=0ba77e739c4c4becbb9a4b44f8820d73
# will inject 'application' namespace in bootstrap phase
apollo.bootstrap.enabled = true
# will inject 'application', 'FX.apollo' and 'application.yml' namespaces in bootstrap phase
#apollo.bootstrap.namespaces = application,FX.apollo,application.yml
apollo.bootstrap.namespaces = application
3.代码实现
ApolloConfigBean
package com.zrj.apollo.platform.config;
import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* ApolloConfigBean
* <p>
* Apollo自动加载热更新问题
* 1、Apollo默认会对Value和ApolloJsonValue注解的数据进行热更新。
* 2、其他数据需要通过ApplicationContext.publishEven刷新到应用中。
* 3、当多个namespace时,优先使用先加载的数据,如namespaces: zone-dev,application,使用zone-dev中数据。
* 方案一:通过ApolloConfigChangeListener监听指定namespace,无法满足根据分区配置namespace。
* 方案二:通过Config.addChangeListener监听指定namespace,动态监听不同的namespace配置。
*
* @author zrj
* @since 2023/1/6
**/
@Data
@Component
public class ApolloConfigBean {
@Value("${timeout:100}")
private int timeout;
@Value("${batch:100}")
private int batch;
@Value("${run:stop}")
private String run;
@Value("${say:hi}")
private String say;
/**
* ApolloJsonValue annotated on fields example, the default value is specified as empty list - []
* <br /> jsonBeanProperty=[{"someString":"hello","someInt":100},{"someString":"world!","someInt":200}]
*/
@ApolloJsonValue("${jsonBeanProperty:[]}")
private List<JsonBean> jsonBeans;
private static class JsonBean {
private String someString;
private int someInt;
@Override
public String toString() {
return "JsonBean{" +
"someString='" + someString + '\'' +
", someInt=" + someInt +
'}';
}
}
}
ApolloConfigListener
package com.zrj.apollo.platform.config;
import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.spring.events.ApolloConfigChangeEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import java.util.Set;
/**
* apollo监听器
*
* @author zrj
* @since 2023/1/6
**/
public class ApolloConfigListener implements ApplicationListener<ApolloConfigChangeEvent> {
private static final Logger logger = LoggerFactory.getLogger(ApolloConfigListener.class);
@Override
public void onApplicationEvent(ApolloConfigChangeEvent apolloConfigChangeEvent) {
String namespace = apolloConfigChangeEvent.getConfigChangeEvent().getNamespace();
logger.info("On ApplicationEvent ApolloConfigChangeEvent received, namespace: {}", namespace);
Set<String> changedKeys = apolloConfigChangeEvent.getConfigChangeEvent().changedKeys();
for (String key : changedKeys) {
ConfigChange configChange = apolloConfigChangeEvent.getConfigChangeEvent().getChange(key);
logger.info("configChange received {}", configChange);
}
}
}
ApolloConfig
package com.zrj.apollo.platform.config;
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* apollo配置
*
* @author zrj
* @since 2023/1/6
**/
@Configuration
@EnableApolloConfig
public class ApolloConfig {
@Bean
public ApplicationListener testApplicationListener() {
return new ApolloConfigListener();
}
}
ApolloController
package com.zrj.apollo.platform.controller;
import com.zrj.apollo.platform.config.ApolloConfigBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* apollo
*
* @author zrj
* @since 2023/1/6
**/
@RestController
@RequestMapping("/apollo")
public class ApolloController {
private static final Logger logger = LoggerFactory.getLogger(ApolloController.class);
private final ApolloConfigBean apolloConfigBean;
public ApolloController(ApolloConfigBean apolloConfigBean) {
this.apolloConfigBean = apolloConfigBean;
}
@GetMapping("/get")
public String getApolloConfig() {
String helloTime = "【ApolloController】ApolloConfigBean:" + apolloConfigBean.toString();
logger.info(helloTime);
return helloTime;
}
}
ApolloPlatformApplication
package com.zrj.apollo.platform;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* apollo
* 配置系统启动参数,idea,VM options:-Dapollo.meta=http://127.0.0.1:8080 -Denv=dev
*
* @author zrj
* @since 20230106
*/
@SpringBootApplication
public class ApolloPlatformApplication {
public static void main(String[] args) {
SpringApplication.run(ApolloPlatformApplication.class, args);
}
}
4.配置启动参数
配置系统启动参数,idea,VM options:-Dapollo.meta=http://127.0.0.1:8080 -Denv=dev
5.测试验证
访问地址:http://localhost:8088/apollo/get
访问结果:
【ApolloController】ApolloConfigBean:ApolloConfigBean(timeout=600, batch=900, run=start, jsonBeans=[JsonBean{someString=‘hello’, someInt=100}, JsonBean{someString=‘world!’, someInt=200}])
5.2 集成问题
启动的时候遇到了两个问题,官方文档上也没具体说明,当然也可能是我忽略了,主要是启动参数必须配置,官方案例中也没用配置启动参数拉去配置是没有问题,自己集成的必须配置启动参数才能拉去配置,目前解决方案如下。
启动问题
日志循环打印拉取失败信息,RemoteConfigLongPollService: Long polling failed, will retry in 1 seconds. appId: apollo-platform, cluster: default, namespaces: application, long polling url: null, reason: Get config services failed from 127.0.0.1:8080/services/config?appId=apollo-platform&ip=192.168.3.24
解决方案
这个是未对apollo.meta 属性进行正确赋值,必须是eureka的地址和端口,就是你输入这个url+端口的时候跳转到的是eureka这个界面,而非apollo管理页面,否则必定报错。
配置系统启动参数,idea,VM options:-Dapollo.meta=http://127.0.0.1:8080 -Denv=dev
权限问题
Cause: Server returned HTTP response code: 401 for URL
解决方案
apollo开启了密匙,需要配置正确的密匙。
apollo管理页面:管理密钥。配置文件:apollo.access-key.secret=1cf998c4e2ad4704b45a98a509d15719
5.3 灰度测试
apollo支持灰度发布,可以通过配置灰度版本,灰度规则,根据不同的ip或者标签拉取不同的配置。只有符合灰度规则的机器才能拉取灰度配置。
1.配置灰度
灰度-添加灰度配置-添加灰度规则
2.灰度验证
访问地址:http://localhost:8088/apollo/get
访问结果:
【ApolloController】ApolloConfigBean:ApolloConfigBean(timeout=600, batch=900, run=start, say=hello, jsonBeans=[JsonBean{someString=‘hello’, someInt=100}, JsonBean{someString=‘world!’, someInt=200}])
5.4 热更新问题
Apollo自动加载热更新问题
1、Apollo默认会对Value和ApolloJsonValue注解的数据进行热更新。
2、其他数据需要通过ApplicationContext.publishEven刷新到应用中。
3、当多个namespace时,优先使用先加载的数据,如namespaces: zone-dev,application,使用zone-dev中数据。
方案一:通过ApolloConfigChangeListener监听指定namespace,无法满足根据分区配置namespace。
方案二:通过Config.addChangeListener监听指定namespace,动态监听不同的namespace配置。
6. Apollo问题总结
6.1 Apollo FAQ
Apollo常见问题:https://www.apolloconfig.com/#/zh/faq/faq
Apollo部署&开发问题:https://www.apolloconfig.com/#/zh/faq/common-issues-in-deployment-and-development-phase
6.2 Apollo性能测试报告
Apollo性能测试报告:https://www.apolloconfig.com/#/zh/misc/apollo-benchmark
1.环境配置
机器配置:4C12G
JVM参数:1.8.0_60
Apollo版本:0.9。0
单台机器客户端连接数:5600
集群客户端连接数:10W+
2.性能指标
获取配置Http接口响应时间
QPS: 160
平均响应时间: 0.1ms
95线响应时间: 0.3ms
999线响应时间: 2.5ms
Config Server GC情况
YGC: 平均2Min一次,一次耗时300ms
OGC: 平均1H一次,一次耗时380ms
CPU指标
LoadAverage:0.5
System CPU利用率:6%
Process CPU利用率:8%