一. 背景

在生产环境中,一个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 角色的创建

在命令行执行:

kubectl create role role-configmap-reader --verb=get,list,watch --resource=pods,configmaps --dry-run -o yaml > role-configmap-reader.yml

执行后,会生成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

kubectl create rolebinding rolebinding-pods-configmap-reade- --role=pods-reader --user=qianxunke --dry-run -o yaml > rolebinding-pods-configmap-reader.yaml

执行成功会在当前目录生成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 应用设置session path_kubernetes configmap 热更新spring-boot应用相关推荐

  1. spring boot http status 400_kubernetes configmap 热更新spring-boot应用

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

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

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

  3. spring boot2.x设置session有效时间_Spring 源码解析 Scopes 之 Request 、Session 、Application...

    (给ImportNew加星标,提高Java技能) 转自:开源中国,作者:麦克斯 链接:my.oschina.net/wang5v/blog/3017934 Request.Session.Applic ...

  4. .netcore 如何获取系统中所有session_集群化部署,Spring Security 要如何处理 session 共享?

    前面和大家聊了 Spring Security 如何像 QQ 一样,自动踢掉已登录用户(Spring Boot + Vue 前后端分离项目,如何踢掉已登录用户?),但是前面我们是基于单体应用的,如果我 ...

  5. spring boot设置session超时时长(自定义spring boot session超时时长)

    针对spring boot 2.0 以下版本(亲测1.5.10)设置session超时的方法如下: 1.添加依赖,代码如下: <dependency><groupId>org. ...

  6. Spring Boot 快速上手(9)热部署

    Spring Boot 快速上手(9)热部署 IDE 配置 (idea) 添加依赖 IDE 配置 (idea) 设置 -> 构建.执行.部署 -> 编译器(点击文字) -> (右边界 ...

  7. Spring Boot CLI设置和HelloWorld示例

    Spring Boot CLI设置和HelloWorld示例 在我之前的文章"Spring Boot简介"和"Spring Boot组件和内部"中,我们讨论了S ...

  8. spring boot 有哪些方式可以实现热部署?

    spring boot 有哪些方式可以实现热部署? Spring Loaded spring-boot-devtools JRebel插件 具体操作参考: https://blog.csdn.net/ ...

  9. 17、Spring Boot普通类调用bean【从零开始学Spring Boot】

    转载:http://blog.csdn.net/linxingliang/article/details/52013017 我们知道如果我们要在一个类使用spring提供的bean对象,我们需要把这个 ...

最新文章

  1. sql语句的简单记录
  2. 对抗神经网络,梦,潜意识
  3. NSLog(@%@,类对象); 默认输出类名
  4. cad线加粗怎么设置_原来CAD的线条还可以这样加粗!还能修改初始单位!太实用了...
  5. PowerBI 2019.12更新完美收官2019
  6. dropbox内容更改_Dropbox替代品,Git技巧,Linux技巧,DevOps必须阅读的内容等等
  7. 先进科技计算机视觉,CEEC科技Corner第四期开讲:《3D计算机视觉技术发展与应用》...
  8. 小迪渗透测试学习笔记(一)基础入门-概念名词
  9. cups支持的打印机列表_使用CUPS打印管理器管理打印机
  10. 空间直线同球体交点求解
  11. [Lisp] [Scheme][MacOS]Scheme语言环境搭建
  12. Http响应Response详解
  13. 前端学习路线(前端零基础)
  14. 自己制作脚手架——完整版
  15. AirPods 3和AirPods Pro 哪个值得入手 两者配置对比
  16. 新浪财经50ETF期权和上交所300ETF期权行情接口
  17. 虚拟机磁盘重新分区增加Docker磁盘空间
  18. Windows 找不到 gpedit.msc
  19. Mysql数据库备份(一)
  20. 可汗学院统计学17-24课笔记

热门文章

  1. JavaScript新鲜事·第6期
  2. Android adb常用命令
  3. 编译openjdk源码
  4. Qt 提取文件(exe, dll等)中的图标icon
  5. Ext 整合 Jquery
  6. 注意了,又有企业因BTC费用高转向BCH
  7. ES6中新增的字符串方法
  8. ASP.NET Atlas学习团队建议收集
  9. 面向对象的本质是算法的上下文封装,是同一类属的行为接口的一致性
  10. koa中使用cookie 和session