跟我学SpringCloud | 第七篇:Spring Cloud Config 配置中心高可用和refresh
springcloud系列教程 | 第七篇:spring cloud config 配置中心高可用和refresh
springboot: 2.1.6.release
springcloud: greenwich.sr1
如无特殊说明,本系列教程全采用以上版本
1. 引言
上一篇我们聊了spring cloud config 配置中心,并且和github做了集成,我们的server端是单机版的,任何单机版的服务都只能使用与测试环境或者自己做demo测试,生产环境严禁使用单机服务,配置中心在整个微服务体系中都是及其重要的一个节点,尤其是在devops中自动扩容,如果配置中心宕机,那么所有的自动扩容都会失败。
所以这一篇我们聊聊配置中心的高可用,说到高可用,在springcloud体系中,是有注册中心的,那么,我们的配置中心也是一个服务,可不可以使用eureka做服务的注册与发现呢?
答案是肯定的。
2. serve端
我们将上一篇的serve端copy到新的目录中,增加eureka-client的依赖,使得config-serve可以注册到eureka上。
2.1 pom.xml
<?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 http://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.1.6.release</version> <relativepath/> <!-- lookup parent from repository --> </parent> <groupid>com.springcloud</groupid> <artifactid>config-server</artifactid> <version>0.0.1-snapshot</version> <name>config-server</name> <description>demo project for spring boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>greenwich.sr1</spring-cloud.version> </properties> <dependencies> <dependency> <groupid>org.springframework.cloud</groupid> <artifactid>spring-cloud-starter-netflix-eureka-client</artifactid> </dependency> <dependency> <groupid>org.springframework.cloud</groupid> <artifactid>spring-cloud-config-server</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-test</artifactid> <scope>test</scope> </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> </plugin> </plugins> </build> </project>
2.2 配置文件application.yml
server: port: 8080 spring: application: name: spring-cloud-config-server cloud: config: server: git: uri: https://github.com/meteor1993/springcloudlearning search-paths: chapter6/springcloud-config username: username password: password eureka: client: service-url: defaultzone: http://localhost:8761/eureka/
增加eureka的地址配置
2.3 启动类
启动类增加@enableeurekaclient激活对注册中心的支持
package com.springcloud.configserver; import org.springframework.boot.springapplication; import org.springframework.boot.autoconfigure.springbootapplication; import org.springframework.cloud.config.server.enableconfigserver; import org.springframework.cloud.netflix.eureka.enableeurekaclient; @springbootapplication @enableconfigserver @enableeurekaclient public class configserverapplication { public static void main(string[] args) { springapplication.run(configserverapplication.class, args); } }
这样server注册端我们就修改完成了。先启动eureka,再启动serve,在浏览器中访问http://localhost:8761/,就可以看到我们的serve端已经注册到注册中心了,接下来我们开始改造client端。
3. client端
首先还是将上一篇的client端copy过来,和server端一样,增加eureka-client的依赖,使得config-client可以从注册中心上发现服务。
3.1 pom.xml
<?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 http://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.1.6.release</version> <relativepath/> <!-- lookup parent from repository --> </parent> <groupid>com.springcloud</groupid> <artifactid>config-client</artifactid> <version>0.0.1-snapshot</version> <name>config-client</name> <description>demo project for spring boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>greenwich.sr1</spring-cloud.version> </properties> <dependencies> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency> <dependency> <groupid>org.springframework.cloud</groupid> <artifactid>spring-cloud-starter-config</artifactid> </dependency> <dependency> <groupid>org.springframework.cloud</groupid> <artifactid>spring-cloud-starter-netflix-eureka-client</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-test</artifactid> <scope>test</scope> </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> </plugin> </plugins> </build> </project>
3.2 bootstrap.properties
这里我们需要先清空application.yml,所有的配置全都转移到bootstrap.properties中。
spring.application.name=spring-cloud-config-client server.port=8081 spring.cloud.config.name=springcloud-config spring.cloud.config.profile=dev spring.cloud.config.label=master spring.cloud.config.discovery.enabled=true spring.cloud.config.discovery.serviceid=spring-cloud-config-server eureka.client.service-url.defaultzone=http://localhost:8761/eureka/
主要是去掉了spring.cloud.config.uri直接指向server端地址的配置,增加了最后的三个配置:
- spring.cloud.config.discovery.enabled :开启config服务发现支持
- spring.cloud.config.discovery.serviceid :指定server端的name,也就是server端spring.application.name的值
- eureka.client.serviceurl.defaultzone :指向注册中心的地址
3.3 启动类
启动类增加@enableeurekaclient激活对注册中心的支持
package com.springcloud.configclient; import org.springframework.boot.springapplication; import org.springframework.boot.autoconfigure.springbootapplication; import org.springframework.cloud.netflix.eureka.enableeurekaclient; @springbootapplication @enableeurekaclient public class configclientapplication { public static void main(string[] args) { springapplication.run(configclientapplication.class, args); } }
4. 高可用
现在我们来模拟生产环境。
首先,顺次启动eureka,server,client。
在idea启动两个config-serve,我们修改idea配置启动配置,换到8000端口启动config-serve。
先访问http://localhost:8761/,可以看到两个config-serve都正常注册到注册中心。
如上图就可发现会有两个server端同时提供配置中心的服务,防止某一台down掉之后影响整个系统的使用。
我们访问client端的链接:http://localhost:8081/hello, 可以看到页面正常显示:hello dev update1,刷新几次,显示都没问题,现在我们随机停掉一个端口的config-serve服务,再去刷新页面,可以发现,页面依然可以正常显示:hello dev update1。
至此,我们高可用的目的已经达到,但是,不知道各位有没有映像,我们上一篇留了一个坑,服务启动后,我们修改远端github上的配置时,这个配置并不会实时被客户端端所获取到,下面我们来聊一聊有关spring cloud config 刷新的问题。
5. refresh
我们的客户端并不能主动去感知git或者svn的配置变化,从而主动获取最新的配置。那么,客户端如何去主动获取新的配置信息呢?springcloud已经给我们提供了解决方案,每个客户端通过post方法触发各自的/refresh。
修改config-client项目已到达可以refresh的功能。
5.1 添加依赖pom.xml
在我们原有的config-client项目的pom.xml的基础增加新的依赖
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-actuator</artifactid> </dependency>
增加了spring-boot-starter-actuator包,spring-boot-starter-actuator是一套监控的功能,可以监控程序在运行时状态,其中就包括/refresh的功能。
5.2 开启更新机制
需要给加载变量的类上面加载@refreshscope,在客户端执行/refresh的时候就会更新此类下面的变量值。
package com.springcloud.configclient.controller; import org.springframework.beans.factory.annotation.value; import org.springframework.cloud.context.config.annotation.refreshscope; import org.springframework.web.bind.annotation.requestmapping; import org.springframework.web.bind.annotation.restcontroller; /** * @author: shiyao.wei * @date: 2019/7/4 16:19 * @version: 1.0 * @desc: */ @restcontroller @refreshscope // 使用该注解的类,会在接到springcloud配置中心配置刷新的时候,自动将新的配置更新到该类对应的字段中。 public class hellocontroller { @value("${springcloud.hello}") private string hello; @requestmapping("/hello") public string from() { return this.hello; } }
5.3 配置文件bootstrap.properties
spring.application.name=spring-cloud-config-client server.port=8081 spring.cloud.config.name=springcloud-config spring.cloud.config.profile=dev spring.cloud.config.label=master spring.cloud.config.discovery.enabled=true spring.cloud.config.discovery.serviceid=spring-cloud-config-server eureka.client.service-url.defaultzone=http://localhost:8761/eureka/ management.security.enabled=false management.endpoints.web.exposure.include=*
- management.security.enabled: springboot 1.5.x 以上默认开通了安全认证,所以需要添加这个配置
- management.endpoints.web.exposure.include: springboot 2.x 默认只开启了info、health的访问,*代表开启所有访问
5.4 测试
我们先访问客户端的测试连接:http://localhost:8081/hello, 这时,页面的显示是:hello dev update1,我们修改github上的信息,修改为:hello dev update,现在访问http://localhost:8081/hello,得到的信息还是:hello dev update1,现在我们刷新一下客户端,通过cmd命令行执行:curl -x post http://localhost:8081/actuator/refresh,可以看到命令行上有显示:["springcloud.hello","config.client.version"],意味着springcloud.hello这个配置已经刷新,这时,我们再去刷新一下页面,可以看到,页面上得到的信息已经变为了:hello dev update,这时我们refresh成功。
每次手动刷新客户端还是很麻烦,有没有什么办法只要提交代码就自动调用客户端来更新呢,github的webhook是一个好的办法。
6. webhook
webhook是当某个事件发生时,通过发送http post请求的方式来通知信息接收方。webhook来监测你在github.com上的各种事件,最常见的莫过于push事件。如果你设置了一个监测push事件的webhook,那么每当你的这个项目有了任何提交,这个webhook都会被触发,这时github就会发送一个http post请求到你配置好的地址。
如此一来,你就可以通过这种方式去自动完成一些重复性工作,比如,你可以用webhook来自动触发一些持续集成(ci)工具的运作,比如travis ci;又或者是通过 webhook 去部署你的线上服务器。下图就是github上面的webhook配置。
- payload url: 触发后回调的url
- content type: 数据格式,两种一般使用json
- secret: 用作给post的body加密的字符串。采用hmac算法
- events: 触发的事件列表
events事件类型 | 描述 |
---|---|
push | 仓库有push时触发。默认事件 |
create | 当有分支或标签被创建时触发 |
delete | 当有分支或标签被删除时触发 |
这样我们就可以利用hook的机制去触发客户端的更新,但是当客户端越来越多的时候hook支持的已经不够优雅,另外每次增加客户端都需要改动hook也是不现实的。其实spring cloud给了我们更好解决方案,我们在下一篇接着聊。
上一篇: jQuery动态地获取系统时间实现代码
下一篇: Windows迁移打印机与打印队列
推荐阅读
-
Mac苹果笔记本和PC对比介绍
-
iOS xib文件中添加ScrollView约束的方法
-
win2003 mysql单向同步配置步骤[已测]
-
Android中HTTP请求中文乱码解决办法
-
Android编程之绝对布局AbsoluteLayout和相对布局RelativeLayout实例详解
-
解读mysql主从配置及其原理分析(Master-Slave)
-
华为matebook和macbook哪个好 苹果mac和华为matebook详细区别对比评测
-
华为Matebook和Surface Pro 4哪款好?MateBook/Surface Pro4对比评测
-
小米笔记本Air有几种颜色?小米笔记本Air金色和银色哪个颜色好看?
-
华硕ROG GX800怎么样?最强笔记本ROG GX800参数配置详情