一. 背景

在生产环境中,一个app服务处于工作中的状态,此时如果需要临时替换某些配置信息,如数据库连接池大小,链接等,一般都需要在源码端修改配置信息,然后重新部署,可想而知,这样做会影响用户或者其他与其对接的app服务。有没有可以在不重启应用的情况下就可以修改配置信息呢?答案是肯定。 达到热更新的方案还是很多的,如果是java体系,spring-cloud已经为我们提供的一套方案,即spring-cloud-config,本文就不做介绍了。 spring-cloud-kubernetes是springcloud官方推出的开源项目,用于将Spring Cloud和Spring Boot应用运行在kubernetes环境,并且提供了通用的接口来调用kubernetes服务,最终是借用了kubernetes自己的服务发现功能,当configmap发生变动时可通知相关服务更新配置。

二. 实践

1.准备

1.1 应用源码

准备一个spring-boot应用,目录如下:

(1)添加maven依赖

通过maven创建名为springcloudk8sreloadconfigdemo的springboot工程,pom.xml内容如下,要注意的是新增了依赖spring-cloud-starter-kubernetes-config、spring-boot-actuator、spring-boot-actuator-autoconfigure,

<?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 https://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.2.7.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.ftlcloud</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><name>demo</name><description>Demo project for Spring Boot</description><properties><spring-boot.version>2.2.7.RELEASE</spring-boot.version><spring-cloud.version>Hoxton.SR4</spring-cloud.version><maven-checkstyle-plugin.failsOnError>false</maven-checkstyle-plugin.failsOnError><maven-checkstyle-plugin.failsOnViolation>false</maven-checkstyle-plugin.failsOnViolation><maven-checkstyle-plugin.includeTestSourceDirectory>false</maven-checkstyle-plugin.includeTestSourceDirectory><maven-compiler-plugin.version>3.5</maven-compiler-plugin.version><maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version><maven-failsafe-plugin.version>2.18.1</maven-failsafe-plugin.version><maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version><fabric8.maven.plugin.version>3.5.37</fabric8.maven.plugin.version><springcloud.kubernetes.version>1.0.1.RELEASE</springcloud.kubernetes.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-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-actuator-autoconfigure</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-kubernetes-config</artifactId><version>${springcloud.kubernetes.version}</version></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><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin><plugin><!--skip deploy --><groupId>org.apache.maven.plugins</groupId><artifactId>maven-deploy-plugin</artifactId><version>${maven-deploy-plugin.version}</version><configuration><skip>true</skip></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>${maven-surefire-plugin.version}</version><configuration><skipTests>true</skipTests><!-- Workaround for https://issues.apache.org/jira/browse/SUREFIRE-1588 --><useSystemClassLoader>false</useSystemClassLoader></configuration></plugin><plugin><groupId>io.fabric8</groupId><artifactId>fabric8-maven-plugin</artifactId><version>${fabric8.maven.plugin.version}</version><executions><execution><id>fmp</id><goals><goal>resource</goal></goals></execution></executions></plugin></plugins></build><profiles><profile><id>kubernetes</id><build><plugins><plugin><groupId>io.fabric8</groupId><artifactId>fabric8-maven-plugin</artifactId><version>${fabric8.maven.plugin.version}</version><executions><execution><id>fmp</id><goals><goal>resource</goal><goal>build</goal></goals></execution></executions><configuration><enricher><config><fmp-service><type>NodePort</type></fmp-service></config></enricher></configuration></plugin></plugins></build></profile></profiles>
</project>

(2)srcmainresources创建名为bootstrap.yml的文件

如下:

server:port: 8080management:endpoint:restart:enabled: truehealth:enabled: trueinfo:enabled: truespring:application:name: ftl-cloud-app-demoprofiles:active: stagingcloud:kubernetes:reload:#自动更新配置的开关设置为打开enabled: true#更新配置信息的模式是主动拉取mode: polling#主动拉取的间隔时间是500毫秒period: 1000config:sources:- name: ${spring.application.name}namespace: import-staging

可见新增了配置项spring.cloud.kubernetes.reload和spring.cloud.kubernetes.config,前者用于开启自动更新配置,执行更新模式为500毫秒拉取一次,后者指定配置来源于kubernetes的哪个namespace下的哪个configmap。

(3)java源码

需要应用加载的信息如下

## kafka topic相关配置
kafka:topic:group-id: receiver-grouptopic-name:- topic1- topic2- topic3

KafkaTopicProperties.java :

@RefreshScope
@Data
@Component
@ConfigurationProperties("kafka.topic")
public class KafkaTopicProperties {private String groupId;private String[] topicName;public String getGroupId() {return groupId;}public void setGroupId(String groupId) {this.groupId = groupId;}public String[] getTopicName() {return topicName;}public void setTopicName(String[] topicName) {this.topicName = topicName;}
}

TestController.java

@RestController
public class TestController {@Autowiredprivate KafkaTopicProperties properties;@GetMapping("/get")@ResponseBodypublic Object test(){return  properties.getTopicName();}}

DemoApplication.java

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

1.2 configmap创建

即application.yml内容,本文以kafka主题简单配置为例,如下:

## kafka topic相关配置
kafka:topic:group-id: receiver-grouptopic-name:- topic1- topic2- topic3

(1)通过rancher创建configmap

如果k8s通过rancher管理的话,可以通过rancher创建此configmap. 首先,点击资源-配置映射如下:

添加一个配置映射,名称就取我们的demo名称ftl-cloud-app-demo,注意选择命名空间。

点击保存即可创建成功一个名称为ftl-cloud-app-demo的configmap

(2)通过kubectl创建configmap

1)在kubernetes环境新建名为ftl-cloud-app-demo.yml的文件,内容如下:

apiVersion: v1
data:application.yml: |-## kafka topic相关配置kafka:topic:group-id: receiver-grouptopic-name:- topic1- topic2- topic3
kind: ConfigMap
metadata:name: ftl-cloud-app-demonamespace: import-staging

保存后执行:

kubectl apply -f ftl-cloud-app-demo.yml

即可生成名称为ftl-cloud-app-demo的configmap。

2.授权

2.1 角色的创建

在命令行执行:

=get,list,watch --resource

执行后,会生成role-configmap-reader.yml的文件,编辑使之如下:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:namespace: import-stagingname: role-configmap-reader
rules:- apiGroups: [""]resources: ["pods","configmaps"]verbs: ["get", "watch", "list"]

保存,执行

kubectl apply -f role-configmap-reader.yml

即可创建一个拥有"get", "watch", "list" -> "pods","configmaps"权限的角色

2.2 创建ServiceAccount

在命令行执行:

kubectl create serviceaccount qianxunke  -o yaml > user-qianxunke.yml

在当前目录下会生成user-qianxunke.yml的文件,我们需要编辑它,改变默认命名空间(default),如下:

修改好命名空间后,保存执行

kubectl apply -f user-qianxunke.yml

2.3 绑定Role和ServiceAccount

=pods-reader --user

执行成功会在当前目录生成rolebinding-pods-configmap-reader.yaml,编辑其,使之如下:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: rolebinding-pods-configmap-readernamespace: default
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: role-configmap-reader
subjects:- kind: ServiceAccountname: qianxunkenamespace: import-staging

保存,执行:

kubectl apply -f rolebinding-pods-configmap-reader.yaml

3.验证

3.1项目部署

这个根据自己的环境,基本步骤就是:编译镜像,推送镜像到镜像仓库,在k8s中创建模版,执行。 这里我们创建一个无状态的deployment来部署: 内容如下:

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:name: ftl-cloud-app-demo
spec:selector:matchLabels:app: ftl-cloud-app-demoreplicas: 2 # tells deployment to run 2 pods matching the templatetemplate:metadata:labels:app: ftl-cloud-app-demospec:containers:- name: ftl-cloud-app-demoimage: 填写镜像地址ports:- containerPort: 8080serviceAccount: qianxunkeserviceAccountName: qianxunke

注意:serviceAccount,serviceAccountName的值为上文授权的用户名 保存以上内容在ftl-cloud-app-demo-deployment.yml,然后执行

kubectl apply -f ./ftl-cloud-app-demo-deployment.yml

不出意外,程序运行正常。 如果结合rancher部署应用,只需修改已有的deployment,在相应位置添加serviceAccount,serviceAccountName即可。

3.2 验证

在postman输入: http://自己的域名或IP/get 输入如下:

修改configmap

kubectl edit configmap ftl-cloud-app-demo

再在postman点击send,即可马得到如下结果:

4.补充说明

之前的bootstrap.yml中和同步配置相关的参数,如下图红框所示:

polling是定时拉取的模式,间隔时间太大会影响实时性,太小又导致请求过于密集,所以spring-cloud-kubernetes框架还给出了另一种模式:事件通知,对应的值是event; 设置事件通知模式的步骤:先将mode的值从polling改为event,再将period参数注释掉(该参数只在mode等于polling时有效),修改后如下:

spring boot http status 400_kubernetes configmap 热更新spring-boot应用相关推荐

  1. spring boot 应用设置session path_kubernetes configmap 热更新spring-boot应用

    一. 背景 在生产环境中,一个app服务处于工作中的状态,此时如果需要临时替换某些配置信息,如数据库连接池大小,链接等,一般都需要在源码端修改配置信息,然后重新部署,可想而知,这样做会影响用户或者其他 ...

  2. ideadebug热更新_Spring Boot 在IDEA中debug时的hot deployment(热部署)

    因为Spring Boot的项目一般会打包成jar发布, 在开发阶段debug时, 不能像传统的web项目那样, 选择exploded resources进行debug, 也没有热更新按钮, 如果每次 ...

  3. Spring Boot:开发常用的热部署方式汇总

    Spring Boot:开发常用的热部署方式汇总 平时开发Sprig Boot的时候,经常改动个小小的地方就要重新启动项目,这无疑是一种很差的体验.在此,博主收集了3种热部署的方案供大家选择. 正文 ...

  4. 零代码变更,巧用 Reloader 快速实现 Kubernetes 的 Configmap 和 Secret 热更新

    公众号关注 「奇妙的 Linux 世界」 设为「星标」,每天带你玩转 Linux ! 1背景 1.1 配置中心问题 在云原生中配置中心,例如:Configmap和Secret对象,虽然可以进行直接更新 ...

  5. konfig:采用ConfigMap实现线上配置热更新

    前言 利用kubernetes部署应用越来越流行,而运行在kubernetes中的服务需要的各种各样的配置如何才能实现热更新?难道需要在kubernetes中再部署zookeeper或者etcd之类的 ...

  6. Spring Boot/Cloud干货汇总(持续更新:20180226版)

    抽空对本号推送的Spring相关内容做个汇总整理,包括: - Spring - Spring Boot - Spring cloud - 其他Spring干货内容 Spring Boot专题 基础入门 ...

  7. Spring Boot 2.4发布了,但 Spring Cloud 用户不推荐着急升级

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 前段时间Spring Boot发布了本年度最后一个重要更 ...

  8. Spring Boot(2.1.2.RELEASE) + Spring Cloud (Finchley.RELEASE)搭建服务注册和发现组件Eureka

    前言:由于版本原因,部分关于Spring Cloud的书中使用的是Spring Boot 1.x 版本,很多配置或名称在新版本中已经发生了改变.此篇文章记录的是使用较新的Spring Boot 2.x ...

  9. springboot日志写入mysql_44. Spring Boot日志记录SLF4J【从零开始学Spring Boot】

    学院中有Spring Boot相关的课程!点击「阅读原文」进行查看! SpringSecurity5.0视频:http://t.cn/A6ZadMBe Sharding-JDBC分库分表实战: 在开发 ...

最新文章

  1. 三分钟教会你搭建动态网络
  2. 使用UPnP来穿透NAT使内网接口对外网可见
  3. 一次linux服务器load高达600多的异常处理过程
  4. ajax数据传送中文乱码,springmvc 发送ajax出现中文乱码的解决方法汇总
  5. 使用SWig出现调用异常的情况
  6. HTML与CSS基础之常用选择器(一)
  7. 使用CLI设置WildFly绑定地址并关闭
  8. 数论 —— 线性同余方程
  9. java 控制鼠标点击_java中控制鼠标点击的方法
  10. python提供了名称为什么的构造方法_python面向对象编程(1)——基本概念,术语,self,构造器...
  11. node解决request返回内容gzip乱码问题
  12. PostgreSQL在何处处理 sql查询之二十五
  13. Atitti 模板匹配 Listjava.awt.Point matchTemplate(
  14. css inset属性
  15. RISC-V from scratch 4: 写 UART 驱动
  16. java实现简单的 cs架构
  17. 在PCB板上调试104(0.1μF)独石电容驱动MAXIM MAX3232串口芯片的心得
  18. Android okhttp3设置代理(http/https)
  19. 人工智能帮助警方监控社交媒体,会不会太过分了?
  20. 【APICloud系列|5】一键生成APP所有图标

热门文章

  1. 【Spark】一条 SQL 在 Apache Spark 之旅(上)
  2. 【Flink】IncompatibleClassChangeError: Found class org.apache.flink.streaming.runtime.tasks.Processing
  3. Spring Boot 操作 Memcache
  4. typora设置代码不自动换行
  5. hadoop: Operation category READ is not supported in state standby
  6. Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class
  7. eclipse报错Project facet Cloud Foundry Standalone Application version 1.0 is not supported.
  8. linux下安装xz命令
  9. 30G 超大数据文件,如何用一周时间导入生产数据库?
  10. 一招解决IDEA启动慢的困扰