韵达快递小网站怎么做,visual studio,微信购物商城小程序,做的网站第二年续费多钱背景#xff1a;
最近调研使用k8s的ConfigMap来作为springboot项目的配置中心#xff0c;需要实现热更新机制#xff0c;避免pod重启影响业务。
ConfigMap作为挂载卷使用的时候可以更新pod中的配置内容#xff0c;但是业务应用需要能监听并处理这些变更。我在测试的时候已… 背景
最近调研使用k8s的ConfigMap来作为springboot项目的配置中心需要实现热更新机制避免pod重启影响业务。
ConfigMap作为挂载卷使用的时候可以更新pod中的配置内容但是业务应用需要能监听并处理这些变更。我在测试的时候已经可以看到pod中的ConfigMap配置更新了但是业务应用始终没有刷新配置。参考网上各位大神的关于spring-cloud-starter-kubernetes-config的配置一直未能实现业务配置热更新k8s在v1.19之后已经改为其他方式了其他开源方案过于复杂遂改换思路简单点就用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-boot2.7.10
spring-cloud-context3.1.1 实现
1、引入依赖
主要依赖common-io对文件的监听和springcloud刷新上下文
dependencygroupIdcommons-io/groupIdartifactIdcommons-io/artifactIdversion2.16.0/version
/dependency
dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-context/artifactIdversion3.1.1/version
/dependency
完整依赖如下
modelVersion4.0.0/modelVersion
parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.7.10/version
/parent
groupIdcom.example/groupId
artifactIdtest/artifactId
version0.0.1-SNAPSHOT/version
nametest/name
descriptiontest/description
propertiesjava.version17/java.version
/properties
dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-devtools/artifactIdscoperuntime/scopeoptionaltrue/optional/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-actuator/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-actuator-autoconfigure/artifactId/dependencydependencygroupIdcommons-io/groupIdartifactIdcommons-io/artifactIdversion2.16.0/version/dependencydependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-context/artifactIdversion3.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 {Autowiredprivate ConfigMapFileListener configFileListener;Overridepublic void run(String... args) throws Exception {log.info(启动configMap文件监听...);// configMap挂载路径mountPathString 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)Autowiredprivate ContextRefresher contextRefresher;Overridepublic 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 arent 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 doesnt 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)