在头条文章里,我们把Apollo的基础知识分享了。这里我们一起动手实践下!这套文章实践下来,你也就可以掌握 Apollo 的应用和实践啦~ Apollo 配置中心创建项目与配置
接下来我们将创建一个 Apollo 的客户端项目,引用 Apollo 来实现配置动态更新,不过在此之前我们需要提前进入 Apollo Portal 界面,在里面提前创建一个项目并在其配置一个参数,方便后续客户端引入该配置参数,测试是否能动态变化。
我这里是部署到 Kubernetes 中,通过 NodePort 方式暴露出一个端口,打开这个地址登录 Apollo:
在登录后创建项目时,选择部门默认只能选择 Apollo 自带的 测试部门1与测试部门2两个选项。
开始这真让人迷糊,原来 Apoloo 没有修改或新增部门信息的管理节目,只能通过修改数据库,来新增或者修改数据,这里打开 Portal
对月的数据库中的表 ApolloPortalDB
修改 key
为 organizations
的 value
的 json 数据,改成自己对于的部门信息。
修改完数据库部门信息后,重新登录 Apollo Portal,然后创建项目,这时候选择部门可以看到已经变成我们自己修改后的部门信息了,选择我们自定义部门,然后设置应用 ID 为 apollo-test,应用名为 apollo-demo 。
创建完成后进入配置管理界面
创建一个配置参数,方便后续 Apollo 客户端项目引入该参数,进行动态配置测试。
设置 key 为 test
value 为 123456
然后设置一个备注,保存。
创建完成后可以看到配置管理节目新增了一条配置。
接下来我们将此配置通过发布按钮,进行发布。
创建 Apollo 客户端测试项目
这里创建一个 SpringBoot 项目,引入 Apollo 客户端来来实现与 Apollo 配置中心服务端交互。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
</parent>
<groupId>club.mydlq</groupId>
<artifactId>apollo-demo</artifactId>
<version>0.0.1</version>
<name>apollo-demo</name>
<description>Apollo Demo</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
在 application.yml 配置文件中添加下面参数,这里简单介绍下 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 #是否开启 Apollo
namespaces: application #设置 Namespace
eagerLoad:
enabled: false #将 Apollo 加载提到初始化日志系统之前
写一个 Controller 类来输出 test 变量的值,使用了 Spring 的 @Value 注解,用于读取配置文件中的变量的值,这里来测试该值,项目启动后读取到的变量的值是设置在 application 配置文件中的默认值,还是远程 Apollo 中的值,如果是 Apollo 中配置的值,那么再测试在 Apollo 配置中心中改变该变量的值后,这里是否会产生变化。
@RestController
public class TestController {
@Value("${test:默认值}")
private String test;
@GetMapping("/test")
public String test(){
return "test的值为:" + test;
}
}
SpringBoot 项目启动类。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
由于本人的 Apollo 是部署在 Kubernetes 环境中的,JVM 参数中必须添加两个变量:
DEV
就是指定使用开发环境,如果设置为 PRO
就是制定使用生产环境。如果是在 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 或者其它环境下的配置中心。
启动上面的测试用例,然后输入地址 http://localhost:8080/test 查看:
test的值为:123456
可以看到使用的是 Apollo 中配置的 test
参数的值 123456
,而不是默认的值。
修改 Apollo 配置中心参数 test
值为 666666
,然后再次发布。
发布完成后再次输入地址 http://localhost:8080/test 查看:
test的值为:666666
可以看到示例应用中的值已经改变为最新的值。
回滚完成后状态将变为未发布状态,则时候输入地址 http://localhost:8080/test 查看:
test的值为:123456
可以看到已经回滚到之前的 test
配置的值了。
这里我们将 JVM 参数中 Apollo 配置中心地址故意改错:
-Dapollo.configService=http://192.168.2.100:30002 -Denv=DEV
然后输入地址 http://localhost:8080/test 可以看到值为:
test的值为:123456
可以看到显示的值并不是我们定义的默认值,而还是 Apollo 配置中心配置的 test
参数的值。考虑到由于 Apollo 会在本地将配置缓存一份,出现上面原因,估计是缓存生效。当客户端不能连接到 Apollo 配置中心时候,默认使用本地缓存文件中的配置。上面我们配置了本地缓存配置文件存放地址为 "/opt/data/" ,接下来进入缓存目录,找到对应的缓存配置文件,删除缓存配置文件后,重启应用,再次输入地址查看:
test的值为:默认值
删除缓存配置文件后,可以看到输出的值为自己定义的默认值。
这里我们进入 Apollo 配置中心,删除之前创建的 test
参数,然后发布。
然后再次打开地址 http://localhost:8080/test 查看:
test的值为:默认值
可以看到显示的是应用程序中设置的默认值。
对 Apollo 的 Cluster、Namespace 进行探究
在 Apollo 中,配置可以根据不同的环境划分为 Dev(开发)、Prod(生产) 等环境,又能根据区域划分为不同的 Cluster(集群),还能根据配置参数作用功能的不同划分为不同的 Namespace(命名空间),这里探究下,如何使用上述能力。
(1)、Apollo 配置中心 PRO 环境添加参数
打开 Apollo 配置中心,环境列表点击 PRO 环境,然后新增一条配置,和之前例子中参数保持一致,都为 test
参数,创建完成后发布。
然后修改上面的示例项目,将配置参数指定为 PRO 环境
(2)、示例项目修改 application.yml 配置文件
把 apollo.meta
参数改成 RPO 的配置中心地址
......apollo: meta: http://192.168.2.11:30005 #RPO环境配置中心地址 ......
(3)、示例项目修改 JVM 参数
把 apollo.configService
参数改成 PRO 配置中心地址,env
参数的值改为 PRO
。
-Dapollo.configService=http://192.168.2.11:30005 -Denv=PRO
(4)、启动示例项目观察结果
启动示例项目,然后接着输入地址 http://localhost:8080/test 查看信息:
test的值为:abcdefg
可以看到已经改成生成环境配置,所以在实际项目中,如果要更换环境,需要修改 JVM 参数 env
(如果 Apollo 部署在 Kubernetes 环境中,还需要修改 apollo.configService
参数),和修改 application.yml 配置文件的参数 apollo.meta
值。
(1)、创建两个集群
例如在开发过程中,经常要将应用部署到不同的机房,这里分别创建 beijing
、shanghai
两个集群。
(2)、两个集群都配置同样的参数不同的值
在两个集群 beijing
与 shanghai
中,都统一配置参数 test
,并且设置不同的值。
(3)、示例项目 application.yml 修改集群配置参数,并启动项目观察结果
指定集群为 beijing:
......apollo: cluster: beijing #指定使用 beijing 集群......
启动示例项目,然后接着输入地址 http://localhost:8080/test 查看信息:
test的值为:Cluster-BeiJing
可以看到用的是 beijing 集群的配置指定集群为 shanghai:
......apollo: cluster: shanghai #指定使用 shanghai 集群......
启动示例项目,然后接着输入地址 http://localhost:8080/test 查看信息:
test的值为:Cluster-ShangHai
可以看到用的是 shanghai 集群的配置
(1)、创建两个命名空间
命名空间有两种,一种是 public(公开),一种是 private 私有,公开命名空间所有项目都能读取配置信息,而私有的只能 app.id
值属于该应用的才能读取配置。这里创建 dev-1
与 dev-2
两个私有的命名空间,用于测试。
(2)、两个集群都配置同样的参数不同的值
在两个命名空间中,都统一配置参数 test
,并且设置不同的值,设置完后发布。
(3)、示例项目 application.yml 修改命名空间配置参数,并启动项目观察结果
指定命名空间为 dev-1:
......apollo: bootstrap: namespaces: dev-1 #设置 dev-1 命名空间......
启动示例项目,然后接着输入地址 http://localhost:8080/test 查看信息:
test的值为:dev-1 Namespace
可以看到用的是 dev-1 命名空间的配置
指定命名空间为 dev-2:
......apollo: bootstrap: namespaces: dev-2 #设置 dev-1 命名空间......
YAML启动示例项目,然后接着输入地址 http://localhost:8080/test 查看信息:
test的值为:dev-2 Namespace
HTML可以看到用的是 dev-2 命名空间的配置
Kubernetes 的 SpringBoot 应用使用 Apollo 配置中心
这里的 Apollo 和 SpringBoot 应用一般都是基于 Kubernetes 部署的,所以这里简单介绍下,如何在 Kubernetes 环境下部署 SpringBoot 应用且使用 Apollo 作为配置中心。这里项目依旧使用上面的示例,不过首先要将其编译成 Docker 镜像,方便后续部署到 Kubernetes 环境下。
(1)、执行 Maven 编译
首先执行 Maven 命令,将项目编译成一个可执行 JAR。
$ mvn clean install
(2)、准备 Dockerfile
创建构建 Docker 镜像需要的 Dockerfile 文件,将 Maven 编译的 JAR 复制到镜像内部,然后设置两个变量,分别是:
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" ]
(3)、构建 Docker 镜像
执行 Docker Build 命令构建 Docker 镜像。
$ docker build -t mydlqclub/springboot-apollo:0.0.1 .
(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 名称。
springboot-apollo.yaml
apiVersion: v1
kind: Service
metadata:
name: springboot-apollo
spec:
type: NodePort
ports:
- name: server
nodePort: 31080
port: 8080
targetPort: 8080
- name: management
nodePort: 31081
port: 8081
targetPort: 8081
selector:
app: springboot-apollo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: springboot-apollo
labels:
app: springboot-apollo
spec:
replicas: 1
selector:
matchLabels:
app: springboot-apollo
template:
metadata:
name: springboot-apollo
labels:
app: springboot-apollo
spec:
restartPolicy: Always
containers:
- name: springboot-apollo
image: mydlqclub/springboot-apollo:0.0.1
imagePullPolicy: Always
ports:
- containerPort: 8080
name: server
env:
- name: JAVA_OPTS
value: "-Denv=DEV"
##注意修改此处的 mydlqcloud 为你自己的 Namespace 名称
- name: APP_OPTS
value: "
--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: 1000Mi
cpu: 1000m
requests:
memory: 500Mi
cpu: 500m
(2)、部署 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 来测试接口,显示:
test的值为:123456
可以看到能通过 Apollo 获取参数值。
好了,关于Apollo的介绍、使用、测试就到此告一段落了!