首页 > 其他分享 >Springboot整合Apollo配置中心

Springboot整合Apollo配置中心

时间:2023-04-05 20:12:15浏览次数:55  
标签:Apollo Springboot Service 配置 环境 整合 日志 apollo

前言

参考这一篇 在Linux部署Apollo配置中心 可以搭建出一套Apollo配置中心服务,我们在这里重点看看Springboot如何整合Apollo,将配置交给配置中心管理,并在修改后及时生效到服务上。

我们模拟工作中的开发(development,DEV)和生产(production,PRO)两套环境,在下面例子中会实现不同环境下配置切换,需要参考 在Linux部署Apollo配置中心 中多环境方案提前搭建好两套环境的配置中心服务。

完整例子可以参考 GitHub - fruitbasket-litchi-apollo

如果文章有帮助,可以随手关注、点赞、转发下,一起学习进步。

Apollo配置中心设置

配置环境(ENV)

首先我们需要通过Apollo的UI界面中【管理员工具 / 系统参数】配置DEV和PRO环境相关参数,配置完重启UI服务(Portal Service)生效,这样每个项目都会有两套隔离的环境配置。

image-20211208113624886

先配置可支持的环境(Environment,ENV)列表(apollo.portal.envs)为dev,pro,如果有更多个环境需求用逗号隔开就行。

image-20211208105118201

每个环境都有单独的Meta Service、Config Service以及数据库,我们需要指定各环境Meta Service列表(apollo.portal.meta.servers),Meta Service和Config Service是在同一个服务里面,所以这里的地址就等同于Config Service地址。如:

{
"DEV":"http://node1:8080",
"PRO":"http://node2:8080"
}

image-20211208114338317

创建应用

点击主页的【创建应用】按提示填写,需要注意的是应用唯一标识(AppId)在后面应用中会使用到,像部门、负责人、管理员等是权限管理相关信息,在Springboot配置中暂时不会涉及。

image-20211208110827196

image-20211208110918181

点击【提交】后点开项目可以看到配置界面,左边【环境列表】有我们配置的两套环境。

image-20211208111008704

发布配置

image-20211208112141970

我们点击【新增配置】增加我们的Springboot将使用的配置参数,比如日志级别(logging.level.root)。然后在选择集群将两个环境都勾选,这样两套环境都会增加这个配置。

集群是Apollo提供的另一个维度的配置隔离方式,对于一个appId和一个环境,对不同的集群可以有不同的配置。有需要可以参考 Apollo - 集群独立配置说明

image-20211208111309122

点击【保存】可以在项目界面看到新增的配置,点击【发布】才能生效。

image-20211208111436680

为了方便测试不同环境切换,我们将DEV环境的配置进行修改,将日志级别改成DEBUG,保存然后发布生效。

image-20211208132922396

Springboot配置

引入Maven依赖

重点是apollo-client,引入spring-boot-starter-web为了等下提供一个HTTP接口测试。

<properties>
    <java.version>1.8</java.version>
    <maven.compiler.source>${java.version}</maven.compiler.source>
    <maven.compiler.target>${java.version}</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring-boot-dependencies.version>2.3.12.RELEASE</spring-boot-dependencies.version>
    <apollo-client.version>1.9.1</apollo-client.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot-dependencies.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<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>${apollo-client.version}</version>
    </dependency>
</dependencies>

编辑配置文件

resources目录下创建apollo-env.properties配置文件,里面内容是不同环境的Meta Service请求地址,也就是Config Service的地址。跟我么在Apollo配置中心配置的一样,只是格式有点区别。

dev.meta=http://node1:8080
pro.meta=http://node2:8080

再编辑我们的Springboot配置文件application.yml。

app:
  id: fruitbasket-litchi-apollo										# 应用唯一标识
apollo:
  cache-dir: /opt/data/some-cache-dir             # 配置缓存路径
  autoUpdateInjectedSpringProperties: true        # 是否开启 Spring 参数自动更新
  bootstrap:
    enabled: true                                 # 是否开启 Apollo
    namespaces: application                       # 设置命名空间
    eagerLoad:
      enabled: true                               # 饥饿加载

命名空间(apollo.bootstrap.namespaces)用于指定使用的N个配置,用逗号分隔,每个配置包含N个配置项,一个命名空间也相当于一个配置文件。这个配置项默认是application,类型为properties,如我们没有修改,不配置也没关系。创建项目默认有个命名空间为application,格式是properties,刚好跟这个配置对应,如果想自定义命名空间,参考 Apollo - 创建Namespace

配置缓存路径(apollo.cache-dir)会将注册中心拉取的到的配置缓存在这个路径下,如果注册中心都不可用了,还能保证服务能利用本地缓存启动。每个应用会根据appId生成不同的目录,目录定义为[appId]/config-cache/,比如fruitbasket-litchi-apollo/config-cache/。每个命名空间都会生成一个缓存文件保存相关配置项,文件名定义为[appId]-[cluster]-[命名空间+类型],比如fruitbasket-litchi-apollo+default+application.properties。里面内容主要是配置信息,比如:

#Persisted by DefaultConfig
#Wed Dec 08 13:28:43 CST 2021
logging.level.root=DEBUG

饥饿加载(apollo.bootstrap.eagerLoad.enabled)可以让系统初始化之前从Apollo加载配置。如果希望把日志相关的配置(如logging.level.root=infologback-spring.xml中的参数)也放在Apollo管理,就需要开启这个使Apollo的加载顺序放到日志系统加载之前。

增加启动类和测试接口

增加一个Springboot启动类,顺便增加一个Controller接口进行测试。接口返回项目使用的环境(env)和我们配置的日志级别(logging.level.root),同时打印DEBUG级别日志。

import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@EnableApolloConfig
@SpringBootApplication
public class ApolloApplication {

    private static final Logger logger = LoggerFactory.getLogger(ApolloApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(ApolloApplication.class, args);
    }

    @Autowired
    private Environment environment;

    @GetMapping
    public String test() {
        String ret = String.format("env=%s, logging.level.root=%s"
                , environment.getProperty("env"), environment.getProperty("logging.level.root"));
        logger.debug(ret);
        return ret;
    }
}

最后在启动的时候通过JVM启动参数来指定使用的环境,格式如-Denv=DEV。如果使用IDEA启动服务,可以点击【Edit Configurations】,填在VM Options中。

其实还有其他多种方式指定环境或者直接指定Meta Service地址,可以参考使用的 Apollo - 客户端使用指南

测试

使用开发环境(ENV)配置

我们先用开发环境(DEV)配置启动项目,在控制可以看到按我们DEV环境配置输出了DEBUG级别的日志。

其中有段黄色的警告,是说我们没有通过这4种可行方式指定Meta Service地址,因为我们配置方式不是直接指定的,而是通过统一配置到apollo-env.properties中,然后在启动项中指明使用的环境,结果是一样的,可以不用理会。

image-20211208145547137

然后通过[IP]:[端口号]访问我们的测试接口可以看到返回的环境是DEV,日志级别为DEBUG

image-20211208144821321

切换到生产环境(PRO)配置

将JVM启动参数改为-Denv=PRO重启,访问测试接口可以看到配置切换过来了,控制台也不再输出DEBUG级别日志。

image-20211208145734001

测试配置中心断线

让生产环境(PRO)配置中心停机,或者让Springboot服务网络断开访问不到生产环境注册中心。我们从启动日志可以看到,应用初始化前就警告无法同步配置(Sync config from ... failed),连接被拒绝(Connection refused)。

image-20211208150833089

后面服务不断重试,从1秒开始。每次时间间隔为前一次的2倍。

image-20211208150903530

间隔时间到了120秒就不再增长了。

image-20211208151312969

但是我们的测试接口还是能正常访问的,获取到的配置是最后一次生效的环境配置PRO。我们在本地缓存文件fruitbasket-litchi-apollo+default+application.properties中能看到缓存的是PRO环境的配置。

如果我们重启配置中心,或者恢复网络,服务会重试成功不再发出警告。

注册中心动态更新配置

我们修改正在使用的生产环境(PRO)配置,将日志级别由INFO改成DEBUG,然后点【发布】。

image-20211208153319711

重新访问接口可以看到日志级别配置已经改变为DEBUG。但是控制台不会输出测试接口的DEBUG日志,日志系统加载完后修改配置是没用的。在Springboot中本身有很多参数在运行中变更不能生效。

image-20211208153654089

点击【回滚】可以让配置更新到上一个版本,点击发布历史列出之前的变动,然后可以指定回滚到某个版本中。

image-20211208155405715

至于发布配置实时更新的流程可以参考 Apollo - 配置发布后的实时推送设计

大致流程是用户通过IU界面(Portal Service)修改发布配置,修改请求发送到(Admin Service)写到数据库表ReleaseMessage中,Config Service每秒定时去扫描消费这个表中的发布消息(Admin Service和Config Service是使用同一个库),最后通知给客户端(Springboot)。

客户端定时向Config Service接口notifications/v2发起HTTP请求,如果有客户端关心的配置发布,则返回相关的命名空间(Namespace)信息,客户端再发起请求获取该命名空间的最新配置,并更新且缓存到本地。

如果定时拉取配置的请求时,没有客户端关心的配置发布,那保存连接60秒,中间有发布则返回,否则超时返回状态码304。这点跟消息队列RocketMQ、Kafka的长轮询机制差不多。

release-message-notification-design

参考

Apollo - 中文文档

Apollo - 使用指南

Apollo - Java客户端使用指南

GitHub - fruitbasket-litchi-apollo

标签:Apollo,Springboot,Service,配置,环境,整合,日志,apollo
From: https://www.cnblogs.com/shuiyao3/p/17290745.html

相关文章

  • Springboot+ElasticJob-Lite实现集群任务调度
    前言ElasticJob-Lite是集群环境下应用(比如SpringCloud微服务)任务调度的解决方案。集群部署的时候,一个定时任务会有多个进程执行,如果不进行任何处理,会导致任务触发的时候每个进程重复执行一次。解决办法有两种:一种是加锁,保证同时只有一个进程执行任务,比如用分布式锁,或者用任务调......
  • Springboot+Mysql 图书管理系统【源码+sql】
    java项目学生图书管理系统(源码+数据库文件)技术框架:java+springboot+mysql后端框架:SpringBoot、SpringMVC、MyBatisPlus前端界面:Thymeleaf、BootStrap、jQuery系统共分为三种用户系统主要功能:系统设计三个角色,学生端,管理员端,系统管理员端1.普通用户书籍查询、书籍借阅......
  • SSM整合的所有配置(配置文件)
    mybatis-config.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEconfigurationPUBLIC"-//mybatis.org//DTDConfig3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configu......
  • 基于SpringBoot+Vue+ElementUI的在线考试系统(可做毕设)
    项目简介青云是一套麻雀虽小但五脏俱全的在线考试系统。采用了目前主流的技术栈SpringBoot+Vue+ElementUI,并进行了前后端分离。对于事务和锁都有应用,非常适合学习练手。项目演示项目演示地址:http://xuezhabiji.com:5000账号:admin密码:admin代码获取:github:https://github.com......
  • 在Linux部署Apollo配置中心
    前言这篇是参考官网文档总结的Apollo分布式部署方式,包含具体步骤、资源和相关脚本,也在必要的地方给出了资料来源。通过Apollo-中文文档-部署架构可以了解到单机、集群和高可用部署架构的最佳实践方式。安装步骤本篇实践是在Linux系统,使用Apollo1.9.1版本为例,要求环境包含......
  • Springboot 系列 (29) - Springboot+HBase 大数据存储(七)| Springboot 项目通过 Phoeni
    Phoenix是HBase的开源SQL皮肤,通过Phoenix可以使用标准JDBCAPI代替HBase客户端API来创建表,插入数据和查询HBase数据。Phoenix会把SQL编译成一系列的Hbase的scan操作,然后把scan结果生成标准的JDBC结果集,其底层由于使用了Hbase的API,协处理器,过滤器。Pho......
  • springboot +vue2.x实现音乐网站
    1pom文件<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache......
  • 实时决策系统中 OpenMLDB 的常见架构整合方式
    OpenMLDB提供了一个线上线下一致性的实时特征计算平台。对于如何在实际业务系统中整合OpenMLDB,构建完整的机器学习平台,OpenMLDB提供了灵活的支持。本文关注基于OpenMLDB,在企业级业务系统中使用的常见架构。我们主要关注存储和计算两个方面:离在线数据存储架构:如何合理的进行......
  • 实时决策系统中 OpenMLDB 的常见架构整合方式
    OpenMLDB提供了一个线上线下一致性的实时特征计算平台。对于如何在实际业务系统中整合OpenMLDB,构建完整的机器学习平台,OpenMLDB提供了灵活的支持。本文关注基于OpenMLDB,在企业级业务系统中使用的常见架构。我们主要关注存储和计算两个方面:离在线数据存储架构:如何合理的进行离线......
  • 性能环境之Jenkins+Maven自动化部署SpringBoot压测环境(Docker篇)
    前言在上文性能环境之Jenkins+Maven自动化部署SpringBoot压测环境(实战篇)中我们介绍了常规部署流程,本文将在上文的基础上扩展Jenkins+Maven+Docker自动化部署我们的压测环境。关于DockerDocker在这里有什么用?Docker,是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到......