Apollo分布式配置中心

携程框架部门研发的开源配置管理中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端

  • 用户在配置中心对配置进行修改并发布
  • 配置中心通知Apollo客户端有配置更新
  • Apollo客户端从配置中心拉取最新的配置、更新本地配置并通知到应用
    在这里插入图片描述

Apollo支持4个维度管理Key-Value格式的配置:

①、application(应用):

Apollo 客户端在运行时需要知道当前应用是谁,从而可以根据不同的应用来获取对应应用的配置。
每个应用都需要有唯一的身份标识,可以在代码中配置 app.id 参数来标识当前应用,Apollo 会根据此指来辨别当前应用。

②、environment (环境)

  • FAT(Feature Acceptance Test):功能测试环境
  • UAT(User Acceptance Test):集成测试环境
  • DEV(Develop):开发环境
  • PRO(Produce):生产环境

在程序中如果想指定使用哪个环境,可以配置变量 env 的值为对应环境名称即可。

③、cluster (集群)

一个应用下不同实例的分组,比如典型的可以按照数据中心分,把上海机房的应用实例分为一个集群,把北京机房的应用实例分为另一个集群。
对不同的集群,同一个配置可以有不一样的值,比如说上面所指的两个北京、上海两个机房设置两个集群,两个集群中都有 mysql 配置参数,其中参数中配置的地址是不一样的

④、namespace (命名空间)

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

熟悉 SpringBoot 的都知道,SpringBoot 项目都有一个默认配置文件 application.yml,如果还想用多个配置,可以创建多个配置文件来存放不同的配置信息,通过指定 spring.profiles.active 参数指定应用不同的配置文件。这里的 namespace 概念与其类似,将不同的配置放到不同的配置 namespace 中

Namespace 分为两种权限:

  • public(公共的): public权限的 Namespace,能被任何应用获取。
  • private(私有的): 只能被所属的应用获取到。一个应用尝试获取其它应用 private 的 Namespace,Apollo 会报 “404” 异常

Namespace 分为三种类型:

  • 私有类型: 私有类型的 Namespace 具有 private 权限。例如 application Namespace 为私有类型
  • 公共类型: 公共类型的 Namespace 具有 public 权限。公共类型的N amespace 相当于游离于应用之外的配置,且通过 Namespace 的名称去标识公共 Namespace,所以公共的 Namespace 的名称必须全局唯一。
  • 关联类型(继承类型): 关联类型又可称为继承类型,关联类型具有 private 权限。关联类型的 Namespace 继承于公共类型的 Namespace,将里面的配置全部继承,并且可以用于覆盖公共 Namespace 的某些配置。

本地缓存:

Apollo客户端会把从服务端获取到的配置在本地文件系统缓存一份,用于在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置,不影响应用正常运行。

本地缓存路径默认位于以下路径,所以请确保/opt/data或C:\opt\data\目录存在,且应用有读写权限。
Mac/Linux: /opt/data/{appId}/config-cache
Windows: C:\opt\data{appId}\config-cache

本地配置文件会以下面的文件名格式放置于本地缓存路径下:
{appId}+{cluster}+{namespace}.properties

在这里插入图片描述

  • 客户端和服务端保持了一个长连接,从而能第一时间获得配置更新的推送。客户端发起一个 Http 请求到服务端,服务端会保持住这个连接 60 秒,如果在 60 秒内有客户端关心的配置变化,被保持住的客户端请求会立即返回,并告知客户端有配置变化的 namespace 信息,客户端会据此拉取对应 namespace 的最新配置。如果在 60 秒内没有客户端关心的配置变化,那么会返回 Http 状态码 304 给客户端
  • 客户端还会定时从 Apollo 配置中心服务端拉取应用的最新配置。
  • 这是一个 fallback 机制,为了防止推送机制失效导致配置不更新
  • 客户端定时拉取会上报本地版本,所以一般情况下,对于定时拉取的操作,服务端都会返回 304 - Not Modified
  • 定时频率默认为每 5 分钟拉取一次,客户端也可以通过在运行时指定 apollo.refreshInterval 来覆盖,单位为分钟
  • 客户端从 Apollo 配置中心服务端获取到应用的最新配置后,会保存在内存中。
  • 客户端会把从服务端获取到的配置在本地文件系统缓存一份 在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置。
  • 应用程序从 Apollo 客户端获取最新的配置、订阅配置更新通知。

考虑到会有数万客户端向服务端发起长连,在服务端我们使用了 async servlet(Spring DeferredResult) 来服务 Http Long Polling 请求。

在这里插入图片描述

  • Config Service 提供配置的读取、推送等功能,服务对象是 Apollo 客户端
  • Admin Service 提供配置的修改、发布等功能,服务对象是 Apollo Portal(管理界面)
  • 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 进程中

不同场景下Apollo的可用性:
在这里插入图片描述

一、登录Apollo

部署到 Kubernetes 中,通过 NodePort 方式暴露出一个端口,打开这个地址登录 Apollo:
用户名:apollo 密 码:admin
在这里插入图片描述

二、修改与增加部门数据

在登录后创建项目时,选择部门默认只能选择 Apollo 自带的 测试部门1与测试部门2两个选项。
在这里插入图片描述
Apoloo 没有修改或新增部门信息的管理节目,只能通过修改数据库,来新增或者修改数据,这里打开 Portal 对月的数据库中的表 ApolloPortalDB 修改 key 为 organizations 的 value 的 json 数据,改成自己对于的部门信息。
在这里插入图片描述
①、创建一个项目

修改完数据库部门信息后,重新登录 Apollo Portal,然后创建项目,这时候选择部门可以看到已经变成我们自己修改后的部门信息了,选择我们自定义部门,然后设置应用 ID 为 apollo-test,应用名为 apollo-demo

在这里插入图片描述
进入配置管理界面
在这里插入图片描述

②、创建一个配置参数

方便后续 Apollo 客户端项目引入该参数,进行动态配置测试。
在这里插入图片描述
设置 key 为 test value 为 123456 然后设置一个备注,保存。
在这里插入图片描述
创建完成后可以看到配置管理节目新增了一条配置
在这里插入图片描述
接下来我们将此配置通过发布按钮,进行发布。
在这里插入图片描述

三、创建 Apollo 客户端测试项目

①、依赖Apollo

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>com.ctrip.framework.apollo</groupId><artifactId>apollo-client</artifactId><version>1.4.0</version>
</dependency>

②、配置文件添加参数

在 application.yml 配置文件中添加下面参数,这里简单介绍下 Apollo 参数作用:

  • apollo.meta: Apollo 配置中心地址
  • apollo.cluster: 指定使用某个集群下的配置
  • apollo.bootstrap.enabled: 是否开启 Apollo
  • apollo.bootstrap.namespaces : 指定使用哪个 Namespace 的配置,默认 application
  • apollo.cacheDir=/opt/data/some-cache-dir: 为了防止配置中心无法连接等问题,Apollo 会自动将配置本地缓存一份
  • apollo.autoUpdateInjectedSpringProperties: Spring应用通常会使用 Placeholder 来注入配置,如${someKey:someDefaultValue},冒号前面的是 key,冒号后面的是默认值。如果想关闭 placeholder 在运行时自动更新功能,可以设置为 false
  • apollo.bootstrap.eagerLoad.enabled : 将 Apollo 加载提到初始化日志系统之前,如果设置为 false,那么将打印出 Apollo 的日志信息,但是由于打印 Apollo 日志信息需要日志先启动,启动后无法对日志配置进行修改,所以 Apollo 不能管理应用的日志配置,如果设置为 true,那么 Apollo 可以管理日志的配置,但是不能打印出 Apollo 的日志信息。
#应用配置
server:port: 8080
spring:application:name: apollo-demo#Apollo 配置
app:id: apollo-test                            #应用ID
apollo:cacheDir: /opt/data/                       #配置本地配置缓存目录cluster: default                           #指定使用哪个集群的配置meta: http://192.168.2.11:30002            #DEV环境配置中心地址autoUpdateInjectedSpringProperties: true   #是否开启 Spring 参数自动更新bootstrap:                                enabled: true                            #是否开启 Apollonamespaces: application                  #设置 NamespaceeagerLoad:enabled: false                         #将 Apollo 加载提到初始化日志系统之前

③、创建Controller

@RestController
public class TestController {@Value("${test:默认值}")private String test;@GetMapping("/test")public String test(){return "test的值为:" + test;}
}
//启动类
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}

④、JVM启动参数添加

Apollo 是部署在 Kubernetes 环境中的,JVM 参数中必须添加两个变量:

  • env: 应用使用 Apollo 哪个环境,例如设置为 DEV 就是指定使用开发环境,如果设置为 PRO 就是制定使用生产环境
  • apollo.configService: 指定配置中心的地址,跳过 meta 的配置,在测试时指定 meta 地址无效果。如果 Apollo 是部署在 Kubernetes 中,则必须设置该参数为配置中心地址,如果 Apollo 不是在 Kubernetes 环境中,可以不设置此参数,只设置 meta 参数即可。一般情况下,configService 和 meta 值一致

如果是在 Idea 中启动,可以配置启动参数,加上:

  • -Dapollo.configService=http://192.168.2.11:30002 -Denv=DEV
    在这里插入图片描述

如果是 java 命令启动程序,需要 JVM 加上:

java -Dapollo.configService=http://192.168.2.11:30002 -Denv=DEV -jar apollo-demo.jar

【注意】:
注意:上面 env 指定的环境,要和 apollo.meta 指定 Config 地址的环境一致,例如 -Denv=DEV 即使用开发环境,那么 apollo.meta=http://xxx.xxx.xxx:8080 这个url 的 Config 也是开发环境下的配置中心服务,而不能是 PRO 或者其它环境下的配置中心

⑤、启动项目测试

Ⅰ:测试是否能够获取 Apollo 中设置的值

启动上面的测试用例,然后输入地址 http://localhost:8080/test 查看:
在这里插入图片描述
Ⅱ:测试当 Apollo 中修改参数值后客户端是否能及时刷新

修改 Apollo 配置中心参数 test 值为 666666 ,然后再次发布
在这里插入图片描述
发布完成后再次输入地址 http://localhost:8080/test 查看:
在这里插入图片描述

Ⅲ:测试当 Apollo 执行配置回滚操作时客户端是否能及时改变
在这里插入图片描述
回滚完成后状态将变为未发布状态,则时候输入地址 http://localhost:8080/test 查看:
在这里插入图片描述

Ⅳ:测试当不能访问 Apollo 时客户端的变化

将 JVM 参数中 Apollo 配置中心地址故意改错:

-Dapollo.configService=http://192.168.2.100:30002 -Denv=DEV

然后输入地址 http://localhost:8080/test 可以看到值为:
在这里插入图片描述

Ⅴ:测试当 Apollo 中将参数删除后客户端的变化

进入 Apollo 配置中心,删除之前创建的 test 参数,然后发布。
在这里插入图片描述
然后再次打开地址 http://localhost:8080/test 查看:
在这里插入图片描述

不同环境下的配置

环境划分为 Dev(开发)、Prod(生产) 等环境,又能根据区域划分为不同的 Cluster(集群),还能根据配置参数作用功能的不同划分为不同的 Namespace(命名空间)

①、Apollo 配置中心 PRO 环境添加参数

打开 Apollo 配置中心,环境列表点击 PRO 环境,然后新增一条配置,和之前例子中参数保持一致,都为 test 参数,创建完成后发布。
在这里插入图片描述
然后修改上面的示例项目,将配置参数指定为 PRO 环境:

②、示例项目修改 application.yml 配置文件

把 apollo.meta 参数改成 RPO 的配置中心地址
在这里插入图片描述
③、示例项目修改 JVM 参数

把 apollo.configService 参数改成 PRO 配置中心地址,env 参数的值改为 PRO。

-Dapollo.configService=http://192.168.2.11:30005 -Denv=PRO

④、启动示例项目观察结果

启动示例项目,然后接着输入地址 http://localhost:8080/test 查看信息:
在这里插入图片描述

不同集群下的配置

①、创建两个集群

例如在开发过程中,经常要将应用部署到不同的机房,这里分别创建 beijing、shanghai 两个集群
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

②、两个集群都配置同样的参数不同的值

在两个集群 beijing 与 shanghai 中,都统一配置参数 test,并且设置不同的值。
在这里插入图片描述
在这里插入图片描述

③、示例项目 application.yml 修改集群配置参数,并启动项目观察结果

指定集群为 beijing:
在这里插入图片描述
在这里插入图片描述

不同命名空间下的配置

①、创建两个命名空间

命名空间有两种,一种是 public(公开),一种是 private 私有,公开命名空间所有项目都能读取配置信息,而私有的只能 app.id 值属于该应用的才能读取配置。

这里创建 dev-1 与 dev-2 两个私有的命名空间,用于测试。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

②、两个集群都配置同样的参数不同的值

在两个命名空间中,都统一配置参数 test,并且设置不同的值,设置完后发布。
在这里插入图片描述
③、示例项目 application.yml 修改命名空间配置参数,并启动项目观察结果
在这里插入图片描述
在这里插入图片描述

Kubernetes 的 SpringBoot 应用使用 Apollo 配置中心

一、构建Docker镜像

①、执行 Maven 编译,将项目编译成一个可执行 JAR

 mvn clean install

②、准备 Dockerfile

将 Maven 编译的 JAR 复制到镜像内部,然后设置两个变量,分别是:

  • JAVA_OPTS: Java JVM 启动参数变量,这里需要在这里加一个时区参数
  • APP_OPTS: Spring 容器启动参数变量,方便后续操作时能通过此变量配置 Spring 参数

Dockerfile文件:

FROM openjdk:8u222-jre-slim
VOLUME /tmp
ADD target/*.jar app.jar
RUN sh -c 'touch /app.jar'
ENV JAVA_OPTS="-XX:MaxRAMPercentage=80.0 -Duser.timezone=Asia/Shanghai"
ENV APP_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar $APP_OPTS" ]

③、构建Docker镜像

执行 Docker Build 命令构建 Docker 镜像

docker build -t mydlqclub/springboot-apollo:0.0.1 .

④、创建 SpringBoot 且使用 Apollo 配置中心的 Kubernetes 部署文件

这里创建 Kubernetes 下的 SpringBoot 部署文件 apollo-demo-example.yaml
在之前 Dockerfile 中设置了两个环境变量,JAVA_OPTS 与 APP_OPTS
其中 JAVA_OPTS 变量的值将会作为 JVM 启动参数,APP_OPTS 变量的值将会作为应用的配置参数。所以,这里我们将 Apollo 配置参数放置到变量中,这样一来就可以方便修改与维护 Apollo 的配置信息。

在下面配置的环境变量参数中,设置的配置中心地址为 http://service-apollo-config-server-dev.mydlqclub:8080,这是因为 Apollo 部署在 K8S 环境中,且可以使用域名方式访问,service-apollo-config-server-dev 是应用的 Service 名称,mydlqcloud 是 K8S 下的 Namespace 名称。

apiVersion: v1
kind: Service
metadata:name: springboot-apollo
spec:type: NodePortports:- name: servernodePort: 31080port: 8080targetPort: 8080- name: managementnodePort: 31081port: 8081targetPort: 8081selector:app: springboot-apollo
---
apiVersion: apps/v1
kind: Deployment
metadata:name: springboot-apollolabels:app: springboot-apollo
spec:replicas: 1selector:matchLabels:app: springboot-apollotemplate:metadata:name: springboot-apollolabels:app: springboot-apollospec:restartPolicy: Alwayscontainers:- name: springboot-apolloimage: mydlqclub/springboot-apollo:0.0.1imagePullPolicy: Alwaysports:- containerPort: 8080name: serverenv:- name: JAVA_OPTSvalue: "-Denv=DEV"##注意修改此处的 mydlqcloud 为你自己的 Namespace 名称- name: APP_OPTSvalue: "--app.id=apollo-demo--apollo.bootstrap.enabled=true--apollo.bootstrap.eagerLoad.enabled=false--apollo.cacheDir=/opt/data/--apollo.cluster=default--apollo.bootstrap.namespaces=application--apollo.autoUpdateInjectedSpringProperties=true--apollo.meta=http://service-apollo-config-server-dev.mydlqcloud:8080    "resources:limits:memory: 1000Micpu: 1000mrequests:memory: 500Micpu: 500m

⑤、部署 SpringBoot 应用到 Kubernetes

-n:创建应用到指定的 Namespace 中。

 kubectl apply -f springboot-apollo.yaml -n mydlqcloud

⑥、测试部署的应用接口

上面的应用配置了 NodePort 端口,可以通过此端口访问 Kubernetes 集群内的应用接口
Kubernetes 集群地址为 192.168.2.11 且 NodePort 端口为 31081,所以浏览器访问地址 http://192.168.2.11:31081/test 来测试接口,显示:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/459692.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue前端框架--Vue工程项目问题总结{脚手架 Vue-cli}

Vue脚手架部署问题总结 我所遇到的一共两大问题 只有先执行npm install之后 才能run serve 否则会报错 vue-cli-serve不是内部或者外部的命令&#xff0c;也不是可运行的程序或者批处理文件的错误 1. 运行npm install会报错 2. 运行npm run serve报错 nodejs官网为 https://no…

03-抓包_封包_协议_APP_小程序_PC应用_WEB应用

抓包_封包_协议_APP_小程序_PC应用_WEB应用 一、参考工具二、演示案例&#xff1a;2.1、WEB应用站点操作数据抓包-浏览器审查查看元素网络监听2.2、APP&小程序&PC抓包HTTP/S数据-Charles&Fiddler&Burpsuite2.3、程序进程&网络接口&其他协议抓包-WireSh…

嵌入式学习之Linux入门篇笔记——18,makefile基本语法(下)

配套视频学习链接&#xff1a;http://【【北京迅为】嵌入式学习之Linux入门篇】 https://www.bilibili.com/video/BV1M7411m7wT/?p4&share_sourcecopy_web&vd_sourcea0ef2c4953d33a9260910aaea45eaec8 1.wildcard 函数 格式&#xff1a;$&#xff08;wildcard PAT…

优化 IT 支出和消除浪费的 8 种主要方法

不懈追求最佳 IT 支出对于任何组织的长期可持续发展和成功都至关重要。在这个技术快速进步的时代&#xff0c;您必须做出明智的决策&#xff0c;消除浪费&#xff0c;同时最大限度地提高技术投资的价值。 从进行 IT 成本分析到采用敏捷预算和技术标准化&#xff0c;这些策略对…

网络安全产品之认识准入控制系统

文章目录 一、什么是准入控制系统二、准入控制系统的主要功能1. 接入设备的身份认证2. 接入设备的安全性检查 三、准入控制系统的工作原理四、准入控制系统的特点五、准入控制系统的部署方式1. 网关模式2. 控制旁路模式 六、准入控制系统的应用场景七、企业如何利用准入控制系统…

07 A B 从计数器到可控线性序列机

07. A.从计数器到可控线性序列机 让LED灯按照亮0.25秒。灭0.75秒的状态循环亮灭让LED灯按照亮0.25秒&#xff0c;灭0.5秒&#xff0c;亮0.75秒&#xff0c;灭1秒的状态循环亮灭让LED灯按照指定的亮灭模式亮灭&#xff0c;亮灭模式未知&#xff0c;由用户随即指定。以0.25秒为一…

kubectl 创建 Pod 背后到底发生了什么?

想象一下&#xff0c;如果我想将 nginx 部署到 Kubernetes 集群&#xff0c;我可能会在终端中输入类似这样的命令&#xff1a; $ kubectl run --imagenginx --replicas3然后回车。几秒钟后&#xff0c;你就会看到三个 nginx pod 分布在所有的工作节点上。这一切就像变魔术一样…

SpringBoot + Tess4J 实现本地与远程图片的文字识别

1 前言 1.1 概要 在本文中&#xff0c;我们将探讨如何在Spring Boot应用程序里集成Tess4J来实现OCR&#xff08;光学字符识别&#xff09;&#xff0c;以识别出本地和远程图片中的文字。 我们将从添加依赖说起&#xff0c;然后创建服务类以实现OCR&#xff0c;最后展示如何处…

jxls 2.4.5 —— 动态导出excel 表头与数据

文章目录 前言依赖引入制作导出模板测试类导出效果注意事项 前言 再之前的博客中&#xff0c;介绍了jxls的基础使用。但导出表头属于写死的&#xff0c;并未采取动态渲染。 本次进行动态渲染操作&#xff0c;动态渲染表头和填充数据。 依赖引入 springboot测试项目中&#…

canvas实现涂鸦画板功能

查看专栏目录 canvas实例应用100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

【每日一题】LeetCode——链表的中间结点

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ &#x1f64f;小杨水平有…

C#,字符串相似度的莱文斯坦距离(Levenshtein Distance)算法与源代码

一、莱文斯坦&#xff08;Levenshtein&#xff09; Vladimir I. Levenshtein 弗拉基米尔I列文施坦博士是纠错码理论的先驱&#xff0c;被称为俄罗斯编码理论之父。Levenshtein是莫斯科俄罗斯科学院Keldysh应用数学研究所的研究教授&#xff0c;他的贡献体现在消费者的日常生活中…