为了方便服务配置文件统一管理,更易于部署、维护,所以就需要分布式配置中心组件了,在spring cloud中,有分布式配置中心组件spring cloud config,它支持配置文件放在在配置服务的内存中,也支持放在远程Git仓库里。本项目采用的是springBoot2.0.2版本,版本不一致,配置以及访问会有所变化。
在github上面创建一个项目springCloud-config存放配置文件: https://github.com/ningcs/springCloud-config
创建了一个config-client-dev.properties用于访问,内容: name=ningcs。
为了实现config的高可用,引入eureka,上篇博文已经介绍,
我们在这里只需引入即可
eureka.client.serviceUrl.defaultZone=http://localhost:18170/eureka/
详细eureka代码详见地址: https://github.com/ningcs/stocks/tree/master/eureka-server
创建config服务端:config-server
配置文件
spring.application.name=config-server server.port=18173 spring.profiles.active=dev #eureka配置 eureka.client.serviceUrl.defaultZone=http://localhost:18170/eureka/ # 配置git仓库地址 spring.cloud.config.server.git.uri=https://github.com/ningcs/springCloud-config #配置文件所在的目录 spring.cloud.config.server.git.search-paths=/** # 配置仓库的分支 spring.cloud.config.label=master # 访问git仓库的用户名 spring.cloud.config.server.git.username=ningcs # 访问git仓库的用户密码 如果Git仓库为公开仓库,可以不填写用户名和密码,如果是私有仓库需要填写 spring.cloud.config.server.git.password=xxx
启动类添加@EnableConfigServer
package com.example.demo; 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; @EnableEurekaClient @EnableConfigServer @SpringBootApplication public class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); } }
pom文件
<?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> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <name>config-server</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Finchley.SR1</spring-cloud.version> </properties> <dependencies> <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> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </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>
服务端配置完成,下面验证一下服务端的配置有没有什么问题,依次启动eureka-server、config-server,在浏览器里输入
http://localhost:18173/config-client-dev.properties
name: ningcs
说明访问到了
证明配置服务中心可以从远程程序获取配置信息,http请求地址和资源文件映射如下:,可参考
· /{application}/{profile}[/{label}]
· /{application}-{profile}.yml
· /{label}/{application}-{profile}.yml
· /{application}-{profile}.properties
· /{label}/{application}-{profile}.properties
创建config客户端:config-client
在resources目录下新建文件bootstrap.properties,内容:
#eureka配置 eureka.client.serviceUrl.defaultZone=http://localhost:18170/eureka/ #开启配置服务发现 spring.cloud.config.discovery.enabled=true #配置服务实例名称 spring.cloud.config.discovery.service-id=config-server # 指明配置服务中心的网址 spring.cloud.config.uri=http://localhost:18173 #配置文件所在分支 spring.cloud.config.label=master #配置所使用文件类别 dev-开发,test测试,pro生产 spring.cloud.config.profile=dev #spring.cloud.config.fail-fast:true ##自动刷新配置 默认 health,info management.endpoints.web.exposure.include=refresh,health,info ##是否需要权限拉去,默认是true,如果不false就不允许你去拉取配置中心Server更新的内容 management.security.enabled=false
pom:
<?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> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>config-client</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Finchley.SR1</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </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-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--引入springcloud上下文依赖,使bootstrap配置文件生效--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-context</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </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>
引入springcloud上下文依赖,使bootstrap配置文件生效
<!--引入springcloud上下文依赖,使bootstrap配置文件生效--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-context</artifactId> </dependency>
这里说明一下为什么 要放在bootstrap里面,因为项目启动的时候是先加载bootstrap.properties
在client的bootstrap.properties中可以添加自己的属性配置,但如果有和server端相同的属性配置会以server端的会准。
application.properties配置如下
#spring.profiles.active=dev spring.application.name=config-client server.port=18174 #开启健康检查 #eureka.client.healthcheck.enabled=true info.app.name=@project.name@ info.app.description=@project.description@ info.app.version=@project.version@
启动方法:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @EnableEurekaClient @SpringBootApplication public class ConfigClientApplication { public static void main(String[] args) { SpringApplication.run(ConfigClientApplication.class, args); } }
测试方法:
@RefreshScope @RestController public class MyController { @Value("${name}") String foo; @RequestMapping(value = "/name",method = RequestMethod.GET) public String hi(){ return foo; } @RequestMapping(value = "/hi",method = RequestMethod.GET) public String his(){ return "ok"; } }
启动后在日志里面可以看到/actuator/health、/actuator/info、/actuator/refresh,如没有·说明没有配置成功。
2018-09-03 14:21:38.303 INFO 6000 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/health],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
2018-09-03 14:21:38.304 INFO 6000 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/info],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
2018-09-03 14:21:38.304 INFO 6000 --- [ main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/refresh],methods=[POST],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
看到以下日志说明访问到了config-server
2018-09-03 11:50:54.272 INFO 7492 --- [io-18174-exec-4] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://172.21.122.120:18173/
注: @RefreshScope
开启 SpringCloudConfig 客户端的 refresh
刷新范围,来获取服务端的最新配置,@RefreshScope
要加在声明@Controller
声明的类上,否则refres
h之后Conroller
拿不到最新的值,会默认调用缓存。
操作步骤:
①首先在 https://github.com/ningcs/springCloud-config 修改配置文件config-client-dev.properties
我把ningcs修改为 name=ningcs123
②然后访问 http://localhost:18174/actuator/refresh 会出现你修改的字段名 以及版本号
[
"config.client.version",
"name"
]
③然后调用 http://localhost:18174/name 如果不调用 http://localhost:18174/actuator/refresh则会显示ningcs
每次修改配置文件更新都需要手动刷新配置,这样岂不是很麻烦,当然springcloud也解决了这个问题,
接下来我将引入springcloud-bus实现自动刷新。
新建config-bus-client项目(复制config-client即可)
在bootstarp.properites引入mq配置文件
#配置mq spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=ningcs spring.rabbitmq.password=ningcs123456
pom添加mq jar包:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
总bootstarp.properites配置文件如下:
#eureka配置 eureka.client.serviceUrl.defaultZone=http://localhost:18170/eureka/ #开启配置服务发现 spring.cloud.config.discovery.enabled=true #配置服务实例名称 spring.cloud.config.discovery.service-id=config-server # 指明配置服务中心的网址 spring.cloud.config.uri=http://localhost:18175 #配置文件所在分支 spring.cloud.config.label=master #配置所使用文件类别 dev-开发,test测试,pro生产 spring.cloud.config.profile=dev #spring.cloud.config.fail-fast:true ##自动刷新配置 默认 health,info management.endpoints.web.exposure.include=refresh,health,info ##是否需要权限拉去,默认是true,如果不false就不允许你去拉取配置中心Server更新的内容 management.security.enabled=false #配置mq spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=ningcs spring.rabbitmq.password=ningcs123456
application.properties配置如下:
#spring.profiles.active=dev spring.application.name=config-bus-client server.port=18176 #开启健康检查 #eureka.client.healthcheck.enabled=true info.app.name=@project.name@ info.app.description=@project.description@ info.app.version=@project.version@
①依次启动eureka-server,config-server,config-bus-client ,在 https://github.com/ningcs/springCloud-config 修改配置文件config-bus-client-dev.properties
②手动刷新配置http://172.21.122.120:18175/actuator/refresh
③访问 http://localhost:18176/name 如果显示成功说明已配置完成。
④在 https://github.com/ningcs/springCloud-config 配置webhooks
进入项目 /setting-->webhooks -->add webhook
然后配置url,这样你必须需要一个公网可以访问的地址即可,我这里只是示例。
然后修改config-bus-client-dev.properties 自动刷新配置 。
webhooks理解:
Webhook是一个API概念,并且变得越来越流行。我们能用事件描述的事物越多,webhook的作用范围也就越大。Webhook作为一个轻量的事件处理应用,正变得越来越有用。
准确的说webhoo是一种web回调或者http的push API,是向APP或者其他应用提供实时信息的一种方式。Webhook在数据产生时立即发送数据,也就是你能实时收到数据。这一种不同于典型的API,需要用了实时性需要足够快的轮询。这无论是对生产还是对消费者都是高效的,唯一的缺点是初始建立困难。
Webhook有时也被称为反向API,因为他提供了API规则,你需要设计要使用的API。Webhook将向你的应用发起http请求,典型的是post请求,应用程序由请求驱动。
注:写此博客的时候查阅文献,很多博主springboot2.0版本config-client都配置的
management.endpoints.web.exposure.include=bus-refresh
或者 config-server再加配置 management.endpoints.web.exposure.include=‘*’
我测试多次,均访问报404错误。
后来参考文档: https://blog.csdn.net/alinyua/article/details/80009435
就将配置改为
management.endpoints.web.exposure.include=refresh,health,info
即访问成功,如果有springboot2.0版本使用bus-refresh访问成功的可以留下评论探讨一下。
项目源码地址:
https://github.com/ningcs/stocks