返回介绍

客户端详解

发布于 2024-08-18 11:12:34 字数 11302 浏览 0 评论 0 收藏 0

在学习了关于Spring Cloud Config服务端的大量配置和使用细节之后,接下来我们将通过本节内容继续学习Spring Cloud Config客户端的使用与配置。

URI指定配置中心

Spring Cloud Config的客户端在启动的时候,默认会从工程的classpath中加载配置信息并启动应用。只有当我们配置spring.cloud.config.uri的时候,客户端应用才会尝试连接Spring Cloud Config的服务端来获取远程配置信息并初始化Spring环境配置。同时,我们必须将该参数配置在bootstrap.properties、环境变量或是其他优先级高于应用Jar包内的配置信息中,才能正确加载到远程配置。若不指定spring.cloud.config.uri 参数的话,Spring Cloud Config 的客户端会默认尝试连接http://localhost:8888。

在之前的快速入门示例中,我们就是以这种方式实现的,就如下面的配置,其中spring.application.name和spring.cloud.config.profile用于定位配置信息。

spring.application.name=didispace

spring.cloud.config.profile=dev

spring.cloud.config.uri=http://localhost:7001/

服务化配置中心

在第3章中,我们已经学会了如何构建服务注册中心、如何发现与注册服务。那么Config Server是否也能以服务的方式注册到服务中心,并被其他应用所发现来实现配置信息的获取呢?答案是肯定的。在Spring Cloud中,我们也可以把Config Server视为微服务架构中与其他业务服务一样的一个基本单元。

下面,我们就来详细介绍如何将Config Server注册到服务中心,并通过服务发现来访问 Config Server 并获取 Git 仓库中的配置信息。下面的内容将基于快速入门中实现的config-server和config-client工程来进行改造实现。

服务端配置

- 在config-server的pom.xml中增加spring-cloud-starter-eureka依赖,以实现将分布式配置中心加入Eureka的服务治理体系。

……

<dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-config-server</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-eureka</artifactId>

</dependency>

</dependencies>

……

- 在 application.properties 中配置参数 eureka.client.serviceUrl.defaultZone以指定服务注册中心的位置,详细内容如下:

spring.application.name=config-server

server.port=7001

# 配置服务注册中心

eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

# Git管理配置

spring.cloud.config.server.git.uri=http://git.oschina.net/didispace/SpringCloud-Learning/

spring.cloud.config.server.git.searchPaths=spring_cloud_in_action/config-repo

spring.cloud.config.server.git.username=username

spring.cloud.config.server.git.password=password

- 在应用主类中,新增@EnableDiscoveryClient注解,用来将config-server注册到上面配置的服务注册中心上去。

@EnableDiscoveryClient

@EnableConfigServer

@SpringBootApplication

public class Application {

public static void main(String[]args){

new SpringApplicationBuilder(Application.class).web(true).run(args);}

}

- 启动该应用,并访问http://localhost:1111/,可以在Eureka Server的信息面板中看到config-server已经被注册了。

客户端配置

- 在config-client的pom.xml中新增spring-cloud-starter-eureka依赖,以实现客户端发现config-server服务,具体配置如下:

……

<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-eureka</artifactId>

</dependency>

</dependencies>

……

- 在bootstrap.properties中,按如下配置:

spring.application.name=didispace

server.port=7002

eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

spring.cloud.config.discovery.enabled=true

spring.cloud.config.discovery.serviceId=config-server

spring.cloud.config.profile=dev

其中,通过eureka.client.serviceUrl.defaultZone参数指定服务注册中心,用于服务的注册与发现;再将 spring.cloud.config.discovery.enabled参数设置为true,开启通过服务来访问Config Server的功能;最后利用spring.cloud.config.discovery.serviceId参数来指定Config Server注册的服务名。这里的spring.application.name和spring.cloud.config.profile如之前通过URI的方式访问的时候一样,用来定位Git中的资源。

- 在应用主类中,增加@EnableDiscoveryClient注解,用来发现config-server服务,利用其来加载应用配置:

@EnableDiscoveryClient

@SpringBootApplication

public class Application {

public static void main(String[]args){

new SpringApplicationBuilder(Application.class).web(true).run(args);

}

}

- 沿用之前我们创建的Controller来加载Git中的配置信息:

@RefreshScope

@RestController

public class TestController {

@Value("${from}")

private String from;

@RequestMapping("/from")

public String from(){

return this.from;

}

}

- 完成上述配置之后,我们启动该客户端应用。若启动成功,访问http://localhost:1111/,可以在Eureka Server的信息面板中看到该应用已经被注册成功。

- 访问客户端应用提供的服务http://localhost:7002/from,此时,我们会返回在Git仓库中didispace-dev.properties文件中配置的from属性内容:"git-dev-1.0"。

失败快速响应与重试

Spring Cloud Config的客户端会预先加载很多其他信息,然后再开始连接Config Server进行属性的注入。当我们构建的应用较为复杂的时候,可能在连接Config Server之前花费较长的启动时间,而在一些特殊场景下,我们又希望可以快速知道当前应用是否能顺利地从Config Server获取到配置信息,这对在初期构建调试环境时,可以减少很多等待启动的时间。要实现客户端优先判断Config Server获取是否正常,并快速响应失败内容,只需在bootstrap.properties中配置参数spring.cloud.config.failFast=true即可。

我们可以实验一下,在未配置该参数前,不启动Config Server,直接启动客户端应用,可以获得下面的报错信息。同时,在报错之前,可以看到客户端应用已经加载了很多内容,比如Controller的请求等。

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.testController': Injection of autowired dependencies failed;

加上spring.cloud.config.failFast=true参数之后,再启动客户端应用,可以获得下面的报错信息,并且前置的加载内容少了很多,这样通过该参数有效避免了当Config Server配置有误时,不需要多等待前置的一些加载时间,实现了快速返回失败信息。

java.lang.IllegalStateException: Could not locate PropertySource and the fail fast property is set,failing

上面,我们演示了当Config Server宕机或是客户端配置不正确导致连接不到而启动失败的情况,快速响应的配置可以发挥比较好的效果。但是,若只是因为网络波动等其他间歇性原因导致的问题,直接启动失败似乎代价有些高。所以,Config 客户端还提供了自动重试的功能,在开启重试功能前,先确保已经配置了 spring.cloud.config.failFast=true,再进行下面的操作。

- 在客户端的 pom.xml 中增加 spring-retry 和 spring-boot-starter-aop依赖,具体如下:

<dependencies>

……

<dependency>

<groupId>org.springframework.retry</groupId>

<artifactId>spring-retry</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-aop</artifactId>

</dependency>

……

</dependencies>

- 不需要再做其他任何配置,启动客户端应用,在控制台中可以看到如下内容。客户端在连接Config Server失败之后,会继续尝试,直到第6次失败后,才返回错误信息。通过这样的重试机制,可以避免一些间歇性问题引起的失败导致客户端应用无法启动的情况。

c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at:

http://PC-201602152056:7001/

c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at:

http://PC-201602152056:7001/

c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at:

http://PC-201602152056:7001/

c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at:

http://PC-201602152056:7001/

c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at:

http://PC-201602152056:7001/

c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at:

http://PC-201602152056:7001/

o.s.boot.SpringApplication        : Application startup failed

java.lang.IllegalStateException: Could not locate PropertySource and the fail fast property is set,failing

若对默认的最大重试次数和重试间隔等设置不满意,还可以通过下面的参数进行调整。

- spring.cloud.config.retry.multiplier:初始重试间隔时间(单位为毫秒),默认为1000毫秒。

- spring.cloud.config.retry.initial-interval:下一间隔的乘数,默认为1.1,所以当最初间隔是1000毫秒时,下一次失败后的间隔为1100毫秒。

- spring.cloud.config.retry.max-interval:最大间隔时间,默认为2000毫秒。

- spring.cloud.config.retry.max-attempts:最大重试次数,默认为6次。

获取远程配置

在入门示例中,我们对{application}、{profile}、{label}这些参数已经有了一定的了解。在 Git 仓库中,一个形如{application}-{profile}.properties 或{application}-{profile}.yml的配置文件,通过URL请求和客户端配置的访问对应可以总结如下。

- 通过向Config Server发送GET请求以直接的方式获取,可用下面的链接形式。

- 不带{label}分支信息,默认访问master分支,可使用:

□/{application}-{profile}.yml

□/{application}-{profile}.properties

- 带{label}分支信息,可使用:

□/{label}/{application}-{profile}.yml

□/{application}/{profile}[/{label}]

□/{label}/{application}-{profile}.properties

- 通过客户端配置方式加载的内容如下所示。

- spring.application.name:对应配置文件中的{application}内容。

- spring.cloud.config.profile:对应配置文件中{profile}内容。

- spring.cloud.config.label:对应分支内容,如不配置,默认为master。

动态刷新配置

有时候,我们需要对配置内容做一些实时更新,那么Spring Cloud Config是否可以实现呢?答案显然是可以的。下面,我们以快速入门中的示例作为基础,看看如何进行改造来实现配置内容的实时更新。

首先,回顾一下,当前我们已经实现了哪些内容。

- config-repo:定义在Git仓库中的一个目录,其中存储了应用名为didispace的多环境配置文件,配置文件中有一个from参数。

- config-server:配置了Git仓库的服务端。

- config-client:指定了 config-server 为配置中心的客户端,应用名为didispace,用来访问配置服务器以获取配置信息。该应用中提供了一个/from接口,它会获取config-repo/didispace-dev.properties中的from属性返回。

在改造程序之前,我们先将config-server和config-client都启动起来,并访问客户端提供的REST 接口http://localhost:7002/from来获取配置信息,获得的返回内容为git-dev-1.0。接着,我们可以尝试使用Git工具修改当前配置的内容,比如,将 config-repo/didispace-dev.properties 中的 from 的值从 from=gitdev-1.0修改为from=git-dev-2.0,再访问http://localhost:7002/from,可以看到其返回内容还是git-dev-1.0。

接下来,我们将在config-client端做一些改造以实现配置信息的动态刷新。

- 在config-client的pom.xml中新增spring-boot-starter-actuator监控模块。其中包含了/refresh 端点的实现,该端点将用于实现客户端应用配置信息的重新获取与刷新。

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-actuator</artifactId>

</dependency>

- 重新启动config-client,访问一次http://localhost:7002/from,可以看到当前的配置值。

- 修改Git仓库config-repo/didispace-dev.properties文件中from的值。

- 再访问一次http://localhost:7002/from,可以看到配置值没有改变。

- 通过 POST 请求发送到http://localhost:7002/refresh,我们可以看到返回内容如下,代表from参数的配置内容被更新了:

[

"from"

]

- 再访问一次http://localhost:7002/from,可以看到配置值已经是更新后的值了。

通过上面的介绍,大家不难想到,该功能还可以同Git仓库的Web Hook功能进行关联,当有 Git 提交变化时,就给对应的配置主机发送/refresh 请求来实现配置信息的实时更新。但是,当我们的系统发展壮大之后,维护这样的刷新清单也将成为一个非常大的负担,而且很容易犯错,那么有什么办法可以解决这个复杂度呢?后续我们将介绍如何通过Spring Cloud Bus来实现以消息总线的方式进行配置变更的通知,并完成集群上的批量配置更新。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文