赞
踩
Spring Cloud系列教程的所有博客均在下方的目录链接中,方便大家查找和阅读。建议按照顺序学习,对于项目搭建有疑问的可以着重看目录里的第二篇博客。
Spring cloud学习专栏目录
1. 配置不能集中管理
在我们的微服务架构中可能有几百个微服务,如果单独去管理每一个微服务那么我们来假设一种情况。有一天我们的数据源发生了变化,那么每个微服务都要去做相应的修改然后再重新启动,这个维护成本是极大的。
2. 无法做到不同环境不同配置
开发过程中会有开发环境、测试环境、生产环境等。他们的配置都是不一样的,虽然对于某一个微服务我们可以通过配置文件中的spring.profiles.active来指定使用哪一个配置文件,但是对于几百个微服务这样还是很麻烦。
3. 不能在运行期间动态调整配置
项目已经启动,处于运行之中。我们需要它不停机但是要对配置做出相应的调整,现在无法做到只能重启。也就是说不具备自动刷新的功能。
Spring Cloud Config为分布式系统外部化配置提供了服务器端和客户端的支持,它包括Config Server 和 Config Client两部分。由于Config Server 和 Config Client都实现了对 Spring Environment 和 PropertySource 抽象的映射,因此,Spring Cloud Config 非常适合Spring应用程序,当然也可与任何其他语言编写的应用程序配合使用。
Confg Server: 是一个可横向扩展、集中式的配置服务器。它用于集中管理应用程序各个环境下的配置,默认使用Git存储配置内容(也可使用Subversion、本地文件系统或 Vault存储配置)因此可以很方便地实现对配置的版本控制与内容审计
Config Client: 是Config Server的客户端用于操作存储在 Config Server中的配置属性。
架构图如下所示,config server会从git上拉取我们推送的配置。每个微服务中都有一个config client,服务启动时config client会向config server发起请求获取配置。
新建一个Maven Project
选中刚创建好的config-parent父工程,右键–>new project–>maven module
找到config-parent的pom文件导入依赖。运行后config-server如果报错只需要右键–>maven–>update project即可。
<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>
<groupId>com.springcloud</groupId>
<artifactId>config-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<!-- 导入Spring Cloud的依赖管理 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--整合配置中心-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
<modules>
<module>config-server</module>
</modules>
</project>
在config-server下新建一个包com.spring.configserver,创建启动类ConfigServerApplication,多添加一个@EnableConfigServer注解。
# 配置api端口号
server.port=8060
# tomcat
server.tomcat.uri-encoding=UTF-8
# 服务名称
spring.application.name=config-server
spring.cloud.config.server.git.uri=https://gitee.com/zhi_guo_zheng/ConfigServer.git
spring.cloud.config.server.git.username= 码云的用户名
spring.cloud.config.server.git.password= 码云的密码
因为我们要从git仓库中获取配置文件,所以这里我们需要安装git,并且使用码云来作为git仓库。这里需要准备两个配置文件application-dev.properties 以及application-prod.properties 来做测试。将两个配置文件推送到git仓库中。
因为是做测试,所以我这里就写了一点内容。两个配置文件也就只有端口号不一样,做一个区分就可以。(这里对于git和码云的使用就不做说明了,具体的使用请看我的另一篇博客)
———————————————————————————————————
配置文件的git.url就在你的码云仓库中点击克隆/下载,然后复制下面的链接即可
启动config-server服务。
浏览器访问 http://localhost:8060/application-prod.properties。可以看到成功访问到了配置文件中的内容,这里出现了中文乱码,在后面我会讲怎么处理。
———————————————————————————————————
在访问一下另一个配置文件 http://localhost:8060/application-dev.properties,可以看到也是没有问题的。
label 默认为master 也就是master分支
/{application}/{profile}/[label]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
所以我们还可以这样请求
http://localhost:8060/application/dev/master
http://localhost:8060/master/application-dev.properties
可以看到这两种也是没有问题的。
如下所示,我们可以对比一下两种写法,为什么会有通配符的写法呢?当前项目中我们的做法是将所有的微服务都放在一个git仓库中,然后通过application.name去为它找到相应的配置文件。这么做的话每一个微服务的隔离性较差,而使用通配符的方法,我们就需要将git仓库用微服务的application.name去命名,做到一个微服务一个仓库,这样就互不干扰。运行时会根据每一个微服务配置文件中配置的application.name去匹配到相应的git仓库,然后获取它的相应配置。对于当前项目来说,如果我们要将微服务分隔开来,对于用户微服务来说我们就是要去新建一个名为microservice-provide-user的仓库,去管理用户微服务的配置。(这里如果还看不太懂的话,看完第四部分config client的讲解你应该就会理解)
这么做的好处举个例子来说,现在有5个微服务交给5个团队去开发,这样的话每个团队只需要维护好自己的仓库就可以了,做的任何修改也不会对别的微服务造成影响。
#当前我们的写法是这样的
spring.cloud.config.server.git.uri=https://gitee.com/zhi_guo_zheng/ConfigServer.git
#使用通配符后
spring.cloud.config.server.git.uri=https://gitee.com/zhi_guo_zheng/{application}
项目启动时先加载 bootstrap.* 中的配置–> 链接config server加载远程配置–> 最后加载application.* 配置文件。(这里的 .* 代表 yml 或 properties)
这里我们用之前的用户微服务做测试,找到用户微服务的父工程的pom文件导入config client的相关依赖。
<!-- 整合config client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
上面说过启动时是先加载bootstrap配置文件,所以我们通过bootstrap去配置向config server获取配置文件,从而让git仓库中的配置优先于本地的配置提前生效。
url: config server服务的地址
profile: 代表选择哪一个配置如 dev prod 等。对应我们之前在git仓库中创建的application-dev、application-prod的 - 后的部分。
label: 代表选择哪一个分支
spring:
cloud:
config:
uri: http://localhost:8060/
profile: dev
label: master
这里为了测试我们在本地的git仓库中多创建一个 .properties文件,然后将他推送到码云上。注意这里命名时我们使用了用户微服务中配置的application.name
———————————————————————————————————
在这里我们只写一行配置,就是配置服务的端口号。
———————————————————————————————————
现在的码云上是这样的有三个配置文件
首先我们先明确一下各个配置文件中的端口配置
用户微服务: application.properties中端口配置为8081
git仓库:
application-dev中端口配置为8777
application-dev中端口配置为8888
microservice-provide-user-dev中端口配置为8999
———————————————————————————————————
启动eureka服务,再启动用户微服务。此时我们只需要去eureka中查看用户微服务启动后的端口是多少就可以知道它读取了哪一个配置文件。
访问http://localhost:8761,此时我们在bootstrap中配置的是dev,可以看到端口号为8999。也就是说明他读取了 microservice-provide-user-dev 中的配置。
———————————————————————————————————
将profile修改为prod再次测试看看结果如何
———————————————————————————————————
访问http://localhost:8761,此时我们在bootstrap中配置的是prod,可以看到端口号为8888。也就是说明他读取了application-prod 中的配置。
这里讲一下,选择配置文件时是先看 application.name 之后再匹配 dev,prod。如果没有找到和 application.name 匹配的,他默认会去加载名为 application 的配置文件。也就是上面的第二次测试,因为没有找到名为microservice-provide-user-prod 的配置文件所以他选择了 application-prod 的配置文件。而如果存在名称匹配的那么他就会根据名称进行选择,正如第一次的测试。同时也说明了bootstrap配置文件是优先于application配置文件的。
找到config-server的父工程config-parent,在它的pom文件中添加安全认证的依赖
<!--安全认证 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
添加用户名和密码的配置
和第三部分的测试一样我们访问:http://localhost:8060/application-dev.properties
———————————————————————————————————
可以看到,跳转到了登录界面。也就是说安全认证起了作用
———————————————————————————————————
输入我们配置的用户名和密码点击登录
———————————————————————————————————
可以看到和之前一样成功访问到了配置文件中的内容
前面我们就也就用用户微服务来测试config client所以就直接对他进行修改,打开用户微服务的bootstrap.yml文件,这里和eureka一样,在url中加上你设置的用户名和密码就可以了
启动config-server、eureka服务、用户微服务。
和之前一样我们还是通过观察用户微服务的端口号来判断它是否读取了配置文件,这里我们的profile配置的是 prod,所以它一个读取如下配置端口为8888。
———————————————————————————————————
访问eureka注册中心,可以看到端口号确实为8888说明在添加了安全认证之后我们成功的获取了配置。
配合Eureka使用的目的是让config server注册到eureka上,从而config client不再需要硬编码config server的地址,否则如果有一天config server的地址发生了变化那么所有的config client都需要做出调整这个维护成本是很大的。
找到config-server的父工程的pom文件,添加eureka的相关依赖
<!--整合eureka-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
再config server的配置文件中,加上注册到eureka的配置。
# 服务注册中心的地址
eureka.client.service-url.default-zone=http://localhost:8761/eureka
在config server的启动类上添加注解 @EnableEurekaClient来启用eureka,到此config server的改动就完成了。
我们的config client是用户微服务,之前已经添加了eureka的依赖和配置,所以这个时候。它的application.properties是不用做修改的,我们只需要对bootstrap.yml做一些改动。
———————————————————————————————————
bootstrap配置修改如下所示
discovery.enable: 是启用服务发现
discovery.service-id:填写的是config server中配置的application.name
因为我们开启了安全认证所以username和password也是不能少的。
#之前的配置
#spring:
# cloud:
# config:
# uri: http://admin:123456@localhost:8060/
# profile: prod
# label: master
###################################################
#现在的配置
spring:
cloud:
config:
profile: dev
label: master
discovery:
enabled: true
service-id: config-server
username: admin
password: 123456
我们启动eureka服务、config server服务、用户微服务。
访问eureka注册中心,可以看到用户微服务的端口号是8999,说明它读取了microservice-provide-user-dev.properties的配置文件。所以config client中的硬编码问题也就解决了。
当我们的项目处于上线运行过程当中,如果此时的需求发生变化。比如用户量增大我们想要修改连接池的最大连接数或是别的一些简单的属性,此时我们不可能因为一个这么小的改动而让项目暂停,重新启动这是不合理的。所以就需要实现项目在运行过程当中的配置刷新。这里我们需要学习Spring cloud bus来做进一步的实现,篇幅有限所以我将这一部分的内容放到之后的博客当中来进行讲解。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。