Springboot监听ConfigMap配置文件自动更新配置

背景:

最近调研使用k8s的ConfigMap来作为springboot项目的配置中心,需要实现热更新机制,避免pod重启影响业务。

ConfigMap作为挂载卷使用的时候可以更新pod中的配置内容,但是业务应用需要能监听并处理这些变更。我在测试的时候已经可以看到pod中的ConfigMap配置更新了,但是业务应用始终没有刷新配置。参考网上各位大神的关于spring-cloud-starter-kubernetes-config的配置,一直未能实现业务配置热更新,有说k8s在v1.19之后已经改为其他方式了,而且本身对k8s不是太熟悉,遂改换思路,简单点,就用java最原始的文件变更监听来手动刷新配置。

相关环境:

macOS: bigsur 11.7.8
docker desktop: 4.22.0 
docker engine: 24.0.5
kubernetes: 1.27.2
openjdk: 17.0.2
spring-boot:2.7.10
spring-cloud-context:3.1.1

实现:

1、引入依赖

主要依赖common-io对文件的监听和springcloud刷新上下文

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.16.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-context</artifactId>
    <version>3.1.1</version>
</dependency>

完整依赖如下 

<modelVersion>4.0.0</modelVersion>
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.10</version>
</parent>
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test</name>
<description>test</description>
<properties>
    <java.version>17</java.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-actuator-autoconfigure</artifactId>
    </dependency>

    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.16.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-context</artifactId>
        <version>3.1.1</version>
    </dependency>
</dependencies>

2、文件监听器

在项目启动后开启监听

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Service;

import java.io.File;

@Slf4j
@Service
public class ConfigMapFileMonitor implements CommandLineRunner {

    @Autowired
    private ConfigMapFileListener configFileListener;

    @Override
    public void run(String... args) throws Exception {
        log.info("启动configMap文件监听...");
        // configMap挂载路径mountPath
        String fileDir = "/app/config/";
        FileAlterationMonitor monitor = new FileAlterationMonitor(1000);
        FileAlterationObserver observer = new FileAlterationObserver(new File(fileDir));
        observer.addListener(configFileListener);
        monitor.addObserver(observer);
        monitor.start();
        log.info("configMap文件监听开始...");
    }

}

3、文件变更处理逻辑

主要用到Springcloud的ContextRefresher.refresh()方法,可能有的配置不需要更新,这里就需要根据实际业务逻辑来决定要更新哪些配置了。

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.concurrent.Executors;

@Slf4j
@Service
public class ConfigMapFileListener extends FileAlterationListenerAdaptor {

    @Qualifier("configDataContextRefresher")
    @Autowired
    private ContextRefresher contextRefresher;

    @Override
    public void onFileChange(File file) {
        log.info("configMap文件变更,异步刷新上下文...");
        Executors.newSingleThreadExecutor().execute(() -> {
            contextRefresher.refresh();
            log.info("异步刷新上下文完成。");
        });
    }
}

4、配置类

需要更新的配置使用配置类加@RefreshScope注解,@Value的方式无法直接更新

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;

@Data
@RefreshScope
@Configuration
@ConfigurationProperties(prefix = "spring.datasource")
public class DatabaseConfig {
    private String url;
    private String username;
    private String password;
}

类似以下方式的配置无法直接更新,可能需要增加一些逻辑,自行处理吧。。。

@Value("${dfs.console.server}")
private String dfsConsoleServer;

补充下,刷新配置不是修改后立即执行的,是有时间间隔的,可以配置,自行研究吧

其他

如果在运行过程中遇到如下错误,需要在k8s中添加相应权限:

o.s.cloud.kubernetes.StandardPodUtils    : Failed to get pod with name:[sdk-test-7b9dd4f586-69vql]. You should look into this if things aren't working as you expect. Are you missing serviceaccount permissions?
io.fabric8.kubernetes.client.KubernetesClientException: Failure executing: GET at: https://10.96.0.1/api/v1/namespaces/default/pods/sdk-test-7b9dd4f586-69vql. Message: Forbidden!Configured service account doesn't have access. Service account may have been revoked. pods "sdk-test-7b9dd4f586-69vql" is forbidden: User "system:serviceaccount:default:default" cannot get resource "pods" in API group "" in the namespace "default".
        at io.fabric8.kubernetes.client.dsl.base.OperationSupport.requestFailure(OperationSupport.java:570) ~[kubernetes-client-4.13.2.jar:na]

 使用如下代码可以监听到配置变更事件,可以针对具体业务看看有没有用吧。

@EventListener
public void envListener(EnvironmentChangeEvent event) {
    System.out.println("conf change: " + event);
}

参考资料:

spring-cloud-kubernetes 实战 二 configmap_spring-cloud-starter-kubernetes-config github-CSDN博客

spring-cloud-kubernetes自动同步k8s的configmap更新_fabric8 更新configmap-CSDN博客

Spring boot实现更改配置文件后自动更新配置-CSDN博客

SpringBoot基础篇配置信息之配置刷新-腾讯云开发者社区-腾讯云 (tencent.com)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

实践遥感卫星场景海洋船只检测,基于YOLOv8全系列【n/s/m/l/x】参数模型开发构建卫星遥感场景下海洋海面船只检测识别系统

遥感相关的实践在我们前面的系列博文中也有相关的一些实践&#xff0c;胡药师基于MASTAR数据集开发构建对应的目标检测系统在前文也有一些介绍&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a; 《基于YOLOv7开发构建MSTAR雷达影像目标检测系统》 《基于yolov5n的轻量…

多角度解析动态住宅IP的多元化应用

动态住宅IP指的是在住宅网络中使用的、能够随时间或用户需求配置的IP地址&#xff0c;能够根据网络状况自动调整&#xff0c;为用户提供更加灵活、高效的上网体验。这种IP地址不是固定不变的&#xff0c;而是会定期自动更换&#xff0c;这种IP地址也让使用者的安全得以保障。 作…

【牛客】【模板】前缀和

原题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 前缀和模板题。 前缀和中数组下标为1~n。 前缀和&#xff1a;pre[i]pre[i-1]a[i]; 某段区间 [l,r]的和&#xff1a;pre[r]-pre[l-1] 3.…

247 基于matlab的梁的振型仿真

基于matlab的梁的振型仿真。利用有限元理论&#xff0c;求二维梁的固有频率和振型。短边固定&#xff0c;给定长度、横截面积&#xff0c;弹性模量及材料密度已知。并对比理论计算结果进行分析。各参数自己设定。程序已调通&#xff0c;可直接运行。 247 梁的振型仿真 固有频率…

顶级SCI优化!24年新算法冠豪猪算法CPO优化无人机集群三维路径规划!先用先发!

声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 目录 结果展示 原理讲解 一、路径长度成本 F1 …

【Linux】Linux——Centos7安装RabbitMQ

目录 安装包准备socaterlang 安装rabbitmq安装命令启动rabbitmq&#xff0c;两种方式查看rabbitmq 启动后的情况配置并开启网页插件关闭防火墙或开放端口测试登录问题配置web端访问账号密码和权限添加用户&#xff0c;后面两个参数分别是用户名和密码.添加权限修改用户角色再次…

ifconfig命令找不到 command not found

问题 今天解决虚拟机的网络问题后&#xff0c;使用ifconfig发现报错命令未找到 解决方案 输入yum install ifconfi的程序安装包 yum install ifconfig 如果显示没有可用软件包 ifconfig&#xff0c;错误&#xff1a;。 就输入yum search ifconfig匹配安装包程序 yum searc…

windows环境下 postgresql v12 绿色版+postgis 3.4.1版本配置,空间数据库迁移

windows环境下 postgresql v12 绿色版+postgis 3.4.1版本配置,空间数据库迁移 一、软件环境 操作系统:windows 11 pg免安装版数据库:postgresql-12.17-1-windows-x64-binaries.zip 下载地址:https://get.enterprisedb.com/postgresql/postgresql-12.18-1-windows-x64-bina…

《构建高效审批系统:架构设计与实践》

在现代企业管理中&#xff0c;审批系统扮演着至关重要的角色&#xff0c;它不仅能够规范业务流程&#xff0c;提高工作效率&#xff0c;还能够增强企业的管理控制力和信息化水平。本文将探讨如何设计和构建一套高效的审批系统架构&#xff0c;以满足企业日常审批需求&#xff0…

Vue3基础(API风格、监听、生命周期、toRefs、组件通信、插槽、axios,Promise)

Vue3基础&#xff08;API风格、监听、生命周期、toRefs、组件通信、插槽、axios&#xff0c;Promise&#xff09; 目录 Vue3基础&#xff08;API风格、监听、生命周期、toRefs、组件通信、插槽、axios&#xff0c;Promise&#xff09;API 风格选项式API组合式API混合式 事件监听…

并发问题系统学习(更新中)

进程、线程 进程&#xff1a;进程是代码在数据集合上的一次运行活动&#xff0c;是系统进行资源分配和调度的基本单位。可以理解为一个java应用。 线程&#xff1a;线程是进程的一个执行路径&#xff0c;一个进程中至少有一个线程&#xff0c;进程中的多个线程共享进程的资源。…

java报错:使用mybatis plus查询一个只返回一条数据的sql,却报错返回了1000多条

今天遇到一个问题 系统线上问题&#xff0c;经常出现这样的问题&#xff0c;刚重启系统时不报错了&#xff0c;可是运行一段时间又会出现。sql已经写了limit 1&#xff0c;mybatis的debug日志也返回total为1&#xff0c;可是却报错返回了1805条数据 乍一看&#xff0c;感觉太不…

Elasticsearch的基本使用

Elasticsearch的基本使用 1.基本概念1.1 文档和字段1.2 索引和映射1.3 mysql与elasticsearch对比 2.索引库2.1 es中mapping映射属性2.2.es中索引库的增删改查 3.文档3.1 新增文档3.2 查询文档3.3 删除文档3.4 修改文档3.4.1 全量修改3.4.2 增量修改3.5 总结 4.DSL查询语法4.1 D…

Redis如何保证数据一致性?

Redis如何保证数据一致性&#xff1f; Redis通常作为持久层数据库&#xff08;例如MySQL&#xff09;的缓存层&#xff0c;如果缓存或者数据库数据发生改变&#xff0c;如何保证双方的数据是一致的&#xff1f; 这其实是要分情况讨论滴&#xff0c;对数据一致性不同的要求有不…

08.图形化界面字体问题处理

图形化界面字体问题处理 发现图形存在乱码&#xff0c;不显示文字 zabbix服务器的字符集所在的路径下&#xff1a; /usr/share/zabbix/assets/fonts 将本地windows系统的字体进行上传&#xff0c;选择一个自己喜欢的字体 上传到系统路径下并且直接覆盖掉 回到web浏览器界面…

什么是Facebook付费广告营销?

Facebook作为全球最大的社交平台之一&#xff0c;成为了跨境卖家不可或缺的营销阵地。它不仅拥有庞大的用户基数&#xff0c;还提供了丰富的广告工具和社群互动功能&#xff0c;让商家能够精准触达目标市场&#xff0c;提升品牌影响力。云衔科技通过Facebook付费广告营销的专业…

【CSS基础--CSS选择器的常见用法】

CSS选择器的常见用法 1.CSS介绍1.1 基本语法规范1.2 引入样式1.3 规范 2. CSS选择器2.1 标签选择器2.2 类选择器2.3 ID选择器2.4 复合选择器 1.CSS介绍 CSS&#xff08;Cascading Style Sheet&#xff09;&#xff0c;层叠样式表&#xff0c;由于控制页面的样式。CSS能够对网页…

HTML批量文件上传2——进度条显示

作者&#xff1a;私语茶馆 非常多的云应用中需要上传文本&#xff0c;包括图片&#xff0c;文件等等&#xff0c;这些批量文件上传&#xff0c;往往涉及到进度条显示&#xff0c;多文件上传等&#xff0c;这里分享一个非常好的案例&#xff0c;来自BootStrapfriendly.com&#…

kubernetes附加组件—图形化管理工具Dashboard

一、介绍 Dashboard是k8s集群管理的一个WebUi&#xff0c;它是k8s的一个附加组件&#xff0c;需要单独部署。 我们可以通过图形化的方法&#xff0c;创建、删除、修改、查询k8s资源。 二、安装部署dashboard组件 Github地址&#xff1a;GitHub - kubernetes/dashboard: Gen…

物联网实战--平台篇之(四)账户后台交互

目录 一、交互逻辑 二、请求验证码 三、帐号注册 四、帐号/验证码登录 五、重置密码 本项目的交流QQ群:701889554 物联网实战--入门篇https://blog.csdn.net/ypp240124016/category_12609773.html 物联网实战--驱动篇https://blog.csdn.net/ypp240124016/category_12631…