微服务 分布式配置中心Apollo详解 绝地灬酷狼 2024-03-30 15:35 29阅读 0赞 #### 微服务 分布式配置中心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 配置中心对比 ### ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3NTgzNjU1_size_16_color_FFFFFF_t_70]总的来看,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配置中心介绍][Apollo]。 本地快速部署请参见[Quick Start][] 演示环境(Demo): http://81.68.181.139 账号/密码:apollo/admin apollo gitee :[https://gitee.com/apolloconfig][https_gitee.com_apolloconfig] apollo github:[https://github.com/apolloconfig][https_github.com_apolloconfig] apollo 官方地址:[https://www.apolloconfig.com/\#/zh/README][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配置中心架构剖析][Apollo 1]。 ![在这里插入图片描述][9e4c079688cb4683ba35b121468954b9.png]可能从架构图并不能很清晰的明白整个架构设计,业务流转,下边给出一些说明结合上图理解相对容易些。 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 模块说明 ### [各个模块说明详见官网说明。][Link 1] ## 4. Apollo安装部署 ## ### 4.1 部署说明 ### 为了让大家更快的上手了解Apollo配置中心,我们这里准备了一个Quick Start,能够在几分钟内在本地环境部署、启动Apollo配置中心。 考虑到Docker的便捷性,我们还提供了Quick Start的Docker版本,如果你对Docker比较熟悉的话,可以参考Apollo Quick Start Docker部署通过[Docker快速部署Apollo][Docker_Apollo]。 不过这里需要注意的是,Quick Start只针对本地测试使用,如果要部署到生产环境,还请另行参考[分布式部署指南。][Link 2] ### 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'; 正常输出 <table> <thead> <tr> <th>Variable_name</th> <th>Value</th> </tr> </thead> <tbody> <tr> <td>version</td> <td>5.7.11</td> </tr> </tbody> </table> ### 3.3 下载安装包 ### 我们准备好了一个Quick Start安装包,大家只需要下载到本地,就可以直接使用,免去了编译、打包过程。 安装包共50M,如果访问github网速不给力的话,可以从百度网盘下载。 从GitHub下载 checkout或下载apollo-build-scripts项目 由于Quick Start项目比较大,所以放在了另外的repository,请注意项目地址 [https://github.com/nobodyiam/apollo-build-scripts][https_github.com_nobodyiam_apollo-build-scripts] 从百度网盘下载 通过[网盘链接下载][Link 3],提取码: 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][http_localhost_8070] Quick Start集成了Spring Security简单认证,更多信息可以参考Portal 实现用户登录功能 2.登录客户端 输入用户名apollo,密码admin后登录 3.首页案例 点击SampleApp进入配置界面,可以看到当前有一个配置timeout=100 配置界面 如果提示系统出错,请重试或联系系统负责人,请稍后几秒钟重试一下,因为通过Eureka注册的服务有一个刷新的延时。 4.可以通过配置中心页面进行简单的操作 创建新的应用,简单配置,开启密匙管理。 ![在这里插入图片描述][701dac6ed2134c0c8ab467b55b3c348a.png]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][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.配置灰度 灰度-添加灰度配置-添加灰度规则 ![在这里插入图片描述][07696869210b41b09327b06e1e56757f.png]![在这里插入图片描述][aa153f48696546849aa35df0d6c47f28.png] 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][https_www.apolloconfig.com_zh_faq_faq] Apollo部署&开发问题:[https://www.apolloconfig.com/\#/zh/faq/common-issues-in-deployment-and-development-phase][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][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% [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3NTgzNjU1_size_16_color_FFFFFF_t_70]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/1f6f885dcf1d49e28fa2a2973012b50b.png [Apollo]: https://www.apolloconfig.com/#/zh/design/apollo-introduction [Quick Start]: https://www.apolloconfig.com/#/zh/deployment/quick-start [https_gitee.com_apolloconfig]: https://gitee.com/apolloconfig [https_github.com_apolloconfig]: https://github.com/apolloconfig [https_www.apolloconfig.com_zh_README]: https://www.apolloconfig.com/#/zh/README [Apollo 1]: https://mp.weixin.qq.com/s/-hUaQPzfsl9Lm3IqQW3VDQ [9e4c079688cb4683ba35b121468954b9.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/e549823bd4cd41d58a51a24c0feaf4dd.png [Link 1]: https://www.apolloconfig.com/#/zh/design/apollo-design?id=_12-%E6%9E%B6%E6%9E%84%E6%A8%A1%E5%9D%97 [Docker_Apollo]: https://www.apolloconfig.com/#/zh/deployment/quick-start-docker [Link 2]: https://www.apolloconfig.com/#/zh/deployment/distributed-deployment-guide [https_github.com_nobodyiam_apollo-build-scripts]: https://github.com/nobodyiam/apollo-build-scripts [Link 3]: https://pan.baidu.com/s/1Ieelw6y3adECgktO0ea0Gg [http_localhost_8070]: http://localhost:8070 [701dac6ed2134c0c8ab467b55b3c348a.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/6f7d4a7ef5fe4cd399fa6e7a6734e0a1.png [https_www.apolloconfig.com_zh_usage_java-sdk-user-guide]: https://www.apolloconfig.com/#/zh/usage/java-sdk-user-guide [07696869210b41b09327b06e1e56757f.png]: https://img-blog.csdnimg.cn/07696869210b41b09327b06e1e56757f.png [aa153f48696546849aa35df0d6c47f28.png]: https://image.dandelioncloud.cn/pgy_files/images/2024/03/30/bf8fd158bfa84174a6fbe4ec9977d003.png [https_www.apolloconfig.com_zh_faq_faq]: https://www.apolloconfig.com/#/zh/faq/faq [https_www.apolloconfig.com_zh_faq_common-issues-in-deployment-and-development-phase]: https://www.apolloconfig.com/#/zh/faq/common-issues-in-deployment-and-development-phase [https_www.apolloconfig.com_zh_misc_apollo-benchmark]: https://www.apolloconfig.com/#/zh/misc/apollo-benchmark
还没有评论,来说两句吧...