Apollo(四)Java客户端接入和使用

Apollo-Portal后台操作

创建项目

要使用Apollo,第一步需要创建项目。

  1. 打开apollo-portal主页
  2. 点击“创建项目”
  3. 输入项目信息

    • 部门:选择应用所在的部门
    • 应用AppId:用来标识应用身份的唯一id,格式为string,需要和客户端app.properties中配置的app.id对应
    • 应用名称:应用名,仅用于界面展示
    • 应用负责人:选择的人默认会成为该项目的管理员,具备项目权限管理、集群创建、Namespace创建等权限
  4. 点击提交
    创建成功后,会自动跳转到项目首页

添加配置项

编辑配置需要拥有这个Namespace的编辑权限,如果发现没有新增配置按钮,可以找项目管理员授权。

  1. 点击新增配置
  2. 输入配置项
  3. 点击提交

发布配置

配置只有在发布后才会真的被应用使用到,所以在编辑完配置后,需要发布配置。

发布配置需要拥有这个Namespace的发布权限,如果发现没有发布按钮,可以找项目管理员授权。

  1. 点击“发布按钮”
  2. 填写发布相关信息,点击发布

创建Java客户端

环境要求

  • Java: 1.7+
  • Guava: 15.0+
    • Apollo客户端默认会引用Guava 19,如果你的项目引用了其它版本,请确保版本号大于等于15.0

必须配置项

AppId

AppId是应用的身份信息,是从服务端获取配置的一个重要信息。

Apollo Meta Server

Apollo支持应用在不同的环境有不同的配置,所以需要在运行提供给Apollo客户端当前环境的Apollo Meta Server信息。默认情况下,meta server和config service是部署在同一个JVM进程,所以meta server的地址就是config service的地址。

为了实现meta server的高可用,推荐通过SLB(Software Load Balancer)做动态负载均衡。Meta server地址也可以填入IP,如http://1.1.1.1:8080,http://2.2.2.2:8080 ,不过生产环境还是建议使用域名(走slb),因为机器扩容、缩容等都可能导致IP列表的变化。

本地缓存路径

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

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

  • Mac/Linux: /opt/data/{appId}/config-cache
  • Windows: C:\opt\data\{appId}\config-cache

本地配置文件会以下面的文件名格式放置于本地缓存路径下:

{appId}+{cluster}+{namespace}.properties

  • appId就是应用自己的appId,如100004458
  • cluster就是应用使用的集群,一般在本地模式下没有做过配置的话,就是default
  • namespace就是应用使用的配置namespace,一般是application
    我配置的是/opt/data/apollo,结果如下图:

    文件内容以properties格式存储,比如如果有两个key,一个是request.timeout,另一个是batch,那么文件内容就是如下格式:
    1
    2
    request.timeout=2000
    batch=2000

可选配置项

有4个可选配置项:

  • Environment
  • Cluster(集群)、
  • 设置内存中的配置项是否保持和页面上的顺序一致
  • 配置访问秘钥

这些选配项在此不做详细讨论,可以参考官方文档-Java客户端使用指南

代码示例

引入apollo-client的依赖
在SpringBoot项目中要引入如下apollo的依赖:

1
2
3
4
5
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>1.4.0</version>
</dependency>

启动类:

1
2
3
4
5
6
7
8
9
10
@SpringBootApplication
public class ApolloBootstrap {

public static void main(String[] args) {
new SpringApplicationBuilder(ApolloBootstrap.class)
.registerShutdownHook(true)
.build(args)
.run();
}
}

接收apollo中配置项的Java bean类:

1
2
3
4
5
6
7
8
9
10
@Getter
@Setter
@ToString
public class ConfigBean {

//后面的100是指coupon_count取不到时的默认值
@Value("${coupon_count:100}")
private Long couponCount;

}

项目配置类:

1
2
3
4
5
6
7
8
9
10
@Configuration
@EnableApolloConfig //配置信息来源Apollo
public class ApplicationConfig {

@Bean
public ConfigBean couponConfig() {
return new ConfigBean();
}

}

application.yml文件中配置:

1
2
3
4
5
app:
id: apollo-test #和apollo中的appid要一致
apollo:
meta: http://192.168.0.104:8080 #meta server地址,也即是ConfigService服务的地址
cacheDir: /opt/data/apollo #缓存文件的目录

单元测试类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ApolloBootstrap.class)
public class MainTest {

@Autowired
private ConfigBean configBean;

@Test
public void testConfig() throws InterruptedException {
while (true) {
System.out.println("------->" + configBean.getCouponCount());
TimeUnit.SECONDS.sleep(2L);
}
}


}

根据打印在控制台上的内容,可见成功获取到了apollo中的配置信息,并且修改apollo上的配置,正在运行的项目也能够获取到最新的配置值。

1
2
3
4
5
6
------->10000
------->10000
2020-07-12 21:28:54.486 INFO 9592 --- [Apollo-Config-1] c.f.a.s.p.AutoUpdateConfigChangeListener : Auto update apollo changed value successfully, new value: 9999, key: coupon_count, beanName: couponConfig, field: com.lzumetal.springcloud.apollo.Config.ConfigBean.couponCount
------->9999
------->9999
------->9999

springboot集成apollo-client的其它配置

在springboot项目中集成apollo-client时,还支持更多的配置功能。比如使用@ConditionalOnProperty的场景或者是有一些spring-boot-starter在启动阶段就需要读取配置做一些事情(如dubbo-spring-boot-project)时,只需要在application.properties中增加

1
apollo.bootstrap.enabled = true

这样配置之后项目在启动时就会注入默认的命名空间(namespace)也即使’application’命名空间的配置。

如果要注入多个namespace的配置,在application.properties中配置如下:

1
2
apollo.bootstrap.enabled = true
apollo.bootstrap.namespaces = application,FX.apollo

这样配置之后项目在启动时会注入’application’、’FX.apollo’两个个namespace的配置。

注意:namespaces 中的顺序是有讲究的,如果’application’和’FX.apollo’中有相同 key ,那么’application’会覆盖掉’FX.apollo’中相同 key 的值。总结即是前覆盖后

------ 本文完 ------