文章目录
- 概述
- 搭建Config Server
- Step1: 新建Config Server微服务,添加依赖
- Step2: 将Config Server 注册到Eureka Server上
- Step3: 启动@EnableConfigServer,将服务变更为Config Server
- Step5: 新建远端Git工程,用于存放配置文件
- Step6: 启动测试
- 搭建Config Client
- Step1.添加spring-cloud-config-client依赖
- Step2. 新建bootstrap.yml
- Step3. 启动artisan-order
- Step4. 验证
- 配置中心的高可用
- Config Server注册到注册中心上的场景
- Config Server未注册到注册中心上的场景
- 修改Eureka Server的默认端口8761的情况
- Step1. 将Eureka的配置下沉到客户端上
- Step2. 注释掉默认配置文件的配置
- 遗留问题
- 代码
概述
入门文章请看我之前整理的博客: Spring Cloud【Finchley】-19Spring Cloud Config之Config Server和Config Client
搭建Config Server
总结下Spring Cloud的三部曲
1. 增加依赖
2. 启用注解@EnableXXX
3. 配置文件
Step1: 新建Config Server微服务,添加依赖
关键依赖如下:
代码语言:javascript复制 <dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-config-serverartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
Step2: 将Config Server 注册到Eureka Server上
2.1启动类增加 @EnableEurekaClient 注解 ,作为Eureka Client 注册到注册中心上去
2.2application.yml 新增配置如下
代码语言:javascript复制spring:
application:
name: artisan-config
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
Step3: 启动@EnableConfigServer,将服务变更为Config Server
2.1启动类增加 @EnableConfigServer注解
2.2application.yml 新增配置如下
又加了个指定端口 9898 和 force-pull 属性 。 完整配置如下
Cannot pull from remote the working tree is not clean. 这种报错可以通过配置强制拉属性force-pull: true
。 由于Spring Cloud配置服务器会复制远程git存储库,如果本地副本变得不干净,那么Spring Cloud配置服务器就不能更新远程存储库中的本地副本。通过设置强制拉属性为true,使Spring Cloud配置服务器从远程存储库中强制pull。
官方指导: https://github.com/spring-cloud/spring-cloud-config/blob/master/docs/src/main/asciidoc/spring-cloud-config.adoc#force-pull-in-git-repositories
Step5: 新建远端Git工程,用于存放配置文件
之前创建了一个远端Git, 地址为: https://github.com/yangshangwei/spring-cloud-config-center 我们就直接拿来用吧
搭建过程: 搭建Config Server的后端存储
为了测试下,我们新建几个order的配置文件 ,放些配置进去
Step6: 启动测试
启动Eureka Server 和 该工程
访问Eureka http://localhost:8761/
访问: http://localhost:9898/artisan-order-dev.yml
basedir的配置看日志
搭建Config Client
上面我们把Order微服务的配置文件放到了远端的Git,自然而然本地的工程直接使用远端存储的配置文件既可以了,本地的配置自然而言就应该不需要了。
Step1.添加spring-cloud-config-client依赖
在Order工程中添加 spring-cloud-config-client 依赖
代码语言:javascript复制 <dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-config-clientartifactId>
dependency>
Step2. 新建bootstrap.yml
代码语言:javascript复制spring:
application:
name: artisan-order
cloud:
config:
profile: dev
# 可配置多个,不推荐使用,因为需要设置具体的ip.服务端修改或者新增IP后,要同步修改
# uri: http://localhost:9898/,http://localhost:9999/
discovery:
# 指定Config Server在服务发现中的service Id ,默认为configserver
service-id: ARTISAN-CONFIG
# 表示使用服务发现组件中的Config Server,而不自己指定Config Server的uri,默认为false
enabled: true
上述配置信息一定要写到bootstrap.yml中。 如果配到了application.yml中,spring.cloud.config.uri 就会访问默认的8888端口,而非配置的端口了。
bootstrap.yml 是被一个父级的 Spring ApplicationContext 加载的,在加载application.yml 的 ApplicationContext之前。配置在 bootstrap.yml 中的属性优先级更高,默认情况下不能被本地配置覆盖。
当启动不了的时候,比如从远端加载不到配置文件的时候,注意观察日志:
代码语言:javascript复制2019-04-04 16:42:41.844 INFO 27888 --- [ restartedMain] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://localhost:9898/
2019-04-04 16:42:45.426 INFO 27888 --- [ restartedMain] c.c.c.ConfigServicePropertySourceLocator : Located environment: name=artisan-order, profiles=[dev], label=null, version=16152eaaf132cd054c2ac538a11fe4bb7fff6583, state=null
2019-04-04 16:42:45.427 INFO 27888 --- [ restartedMain] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name='configService', propertySources=[MapPropertySource {name='configClient'}, MapPropertySource {name='https://github.com/yangshangwei/spring-cloud-config-center/artisan-order.yml'}]}
Step3. 启动artisan-order
启动后观察是否注册到Eureka上
Step4. 验证
代码语言:javascript复制package com.artisan.order.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConfigController {
@Value("${spring.datasource.url}")
private String url;
@GetMapping("/value")
public String getValueFromGit(){
return url;
}
}
获取 spring.datasource.url的值
访问 http://localhost:8081/value
配置中心的高可用
Config Server注册到注册中心上的场景
这种情况最简单,启动多个Config Server即可。 下面我们来验证下
配置中心再启动另外一个端口
可以看到我们启动了两个进程
去Eureka Server上看也可以。
然后重启下artisan-order微服务,观察日志 中的 server url
代码语言:javascript复制Multiple Config Server Urls found listed.
Fetching config from server at : http://localhost:9898/
Located environment: name=artisan-order, profiles=[dev], label=null, version=06a183a4820a618cc1dc53b33d77e22106a9c4e4, state=null
Located property source: CompositePropertySource {name='configService', propertySources=[MapPropertySource {name='configClient'}, MapPropertySource {name='https://github.com/yangshangwei/spring-cloud-config-center/artisan-order-dev.yml'}, MapPropertySource {name='https://github.com/yangshangwei/spring-cloud-config-center/artisan-order.yml'}]}
再次重启下 ,或者多重启几次
代码语言:javascript复制Multiple Config Server Urls found listed.
Fetching config from server at : http://localhost:9999/
Located environment: name=artisan-order, profiles=[dev], label=null, version=06a183a4820a618cc1dc53b33d77e22106a9c4e4, state=null
Located property source: CompositePropertySource {name='configService', propertySources=[MapPropertySource {name='configClient'}, MapPropertySource {name='https://github.com/yangshangwei/spring-cloud-config-center/artisan-order-dev.yml'}, MapPropertySource {name='https://github.com/yangshangwei/spring-cloud-config-center/artisan-order.yml'}]}
停掉9898节点 ,再次重启下artisan-order服务 ,观察日志
Config Server未注册到注册中心上的场景
借助负载均衡设备即可 ,比如 Nginx , F5,A10等等
修改Eureka Server的默认端口8761的情况
如果我们不使用Eureka Server默认的端口呢? 比如我们使用8762
先把Eureka Server的端口改为8762
其他eureka client客户端将 defaultZone修改为 8762端口对应的url .
Step1. 将Eureka的配置下沉到客户端上
改完默认的端口,我们启动Eureka Server , artisan-config , 发现都可以起来
访问: http://localhost:8762/
紧接着我们启动 artisan-order ,报错了。。。。
代码语言:javascript复制2019-04-08 14:47:29.463 ERROR 30340 --- [ restartedMain] c.n.d.s.t.d.RedirectingEurekaHttpClient : Request execution error
com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect
at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:187) ~[jersey-apache-client4-1.19.1.jar:1.19.1]
........
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) ~[na:1.8.0_191]
2019-04-08 14:47:29.466 WARN 30340 --- [ restartedMain] c.n.d.s.t.d.RetryableEurekaHttpClient : Request execution failed with message: java.net.ConnectException: Connection refused: connect
2019-04-08 14:47:29.468 ERROR 30340 --- [ restartedMain] com.netflix.discovery.DiscoveryClient : DiscoveryClient_ARTISAN-ORDER/localhost:artisan-order - was unable to refresh its cache! status = Cannot execute request on any known server
com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:112) ~[eureka-client-1.9.2.jar:1.9.2]
....
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.0.3.RELEASE.jar:2.0.3.RELEASE]
2019-04-08 14:47:29.474 WARN 30340 --- [ restartedMain] com.netflix.discovery.DiscoveryClient : Using default backup registry implementation which does not do anything.
2019-04-08 14:47:29.476 INFO 30340 --- [ restartedMain] com.netflix.discovery.DiscoveryClient : Not registering with Eureka server per configuration
2019-04-08 14:47:29.480 INFO 30340 --- [ restartedMain] com.netflix.discovery.DiscoveryClient : Discovery Client initialized at timestamp 1554706049479 with initial instances count: 0
2019-04-08 14:47:29.590 WARN 30340 --- [ restartedMain] lientConfigServiceBootstrapConfiguration : Could not locate configserver via discovery
java.lang.IllegalStateException: No instances found of configserver (ARTISAN-CONFIG)
at org.springframework.cloud.config.client.ConfigServerInstanceProvider.getConfigServerInstances(ConfigServerInstanceProvider.java:25) ~[spring-cloud-config-client-2.0.0.RELEASE.jar:2.0.0.RELEASE]
....
一看就知道是Eureka 的问题,我们想到,统一配置中心上artisan-order-dev.yml的Eureka Server的端口还没改,改下再试试吧
访问下 http://localhost:9898/artisan-order-dev.yml 看下效果
再次启动artisan order ,还是报错
访问了配置中心的默认端口8888 ,
这样的话 我们把Eureka的配置
代码语言:javascript复制# Eureka
eureka:
client:
service-url:
defaultZone: http://localhost:8762/eureka/
下沉到artisan order 中
意思就是:启动的时候会优先加载bootstrap中的配置,从该配置文件中找到注册中心的地址,然后再注册中心上去找配置中心的service-id .
同时把配置中心artisan-order-dev.yml 中的eureka的配置注释或者删掉。
Step2. 注释掉默认配置文件的配置
再次访问下 http://localhost:9898/artisan-order-dev.yml 看下
怎么又是8761了。。。。
我们来观察下 artisan cofig的日志
当我们按照这种格式访问 http://localhost:9898/artisan-order-dev.yml 配置文件时,config server同时也会把默认配置文件的artisan-order中的配置合并后返回。
那看下 artisan-order.yml的配置看下吧
把artisan-order.yml的配置注释掉吧
再次访问 http://localhost:9898/artisan-order-dev.yml
可以发现已经没有eureka的相关信息了。
再次启动artisan order ,启动成功。 查看注册中心 http://localhost:8762/
遗留问题
修改配置自动刷新,还是没有实现,仅仅实现了从远端Git读取配置的功能,下一篇我们来实战下如何通过Spring Cloud Bus自动刷新配置
代码
配置文件远端存储Git: https://github.com/yangshangwei/spring-cloud-config-center artisan order : https://github.com/yangshangwei/springcloud-o2o/tree/master/artisan_order artisan config: https://github.com/yangshangwei/springcloud-o2o/tree/master/artisan_config eureka server : https://github.com/yangshangwei/springcloud-o2o/tree/master/eureka-server