spring cloud 系列现在只是分享一些使用教程,比较浅显的分享怎么使用,至于分布式高可用会在后面再来分享
文中所有项目均使用:
IDEA编辑器基于java8进行构建Maven进行依赖管理Git进行版本管理
Spring Cloud版本:Hoxton.BUILD-SNAPSHOT
Spring Boot 版本:2.2.1.BUILD-SNAPSHOT
对于配置文件,相信很多开发者都不陌生,它可以提供动态修改程序运行的能力,对于生产的系统,总需要一些控制可以动态的改变程序的运行状态来贴合实际的需求(比如灰度控制,限流调整等),使得系统可以使用快速变化的市场环境。在单机版的系统服务中,我们称之为配置文件(例如spring boot中的application.yml、application.properties、application.bootstrap等),在分布式集群系统中,我们把配置文件统一放置在服务配置中心系统进行统一管理,称之为服务配置中心系统。
spring-cloud-config为分布式系统外部化配置提供了服务端和客户端的支持,包括config server和config client两部分。支持git、svn、vault、jdbc和本地几种存储方式。
世界上任何事物存在即合理,服务配置中心的存在说明就有这样的需求,需要将各个微服务的配置文件进行统一的管理。
使用服务配置中心之前:
1.不利于维护:
一个微服务在正式上线之前可能存在多种环境,例如开发环境(application-dev.properties)、测试环境(application-test.properties)、生产环境(application-prod.properties)等。在开发人员修改了配置文件之后,都需要重启相应的服务使得配置生效。
假如需要改变一个微服务的配置,而这个微服务部署了n个,运维小哥需要把n个服务都关闭全部重新更改配置之后进行重启服务。这样的操作既繁琐又低效。无法做到快速的动态调整,配置文件也就失去了它主要意义之一。
2.不安全:
配置信息随着源代码保存在代码库里,容易造成配置泄露。
这时候就需要一个更高效快速的方式来修改各个微服务的配置文件来适应需求。在微服务架构中微服务的配置管理一般有以下需求:
git仓库:存储配置文件
config Server:分布式配置管理中心,会维护自己的git仓库信息
本地git:config Server每次从git仓库拉取配置文件之后都会更新自己本地的git仓库,然后本地读取返回,如果远程的giy仓库无法获取,则使用本地的git仓库信息。
这里以git为例
首先先在远程仓库(我使用的是gitee,当然也可以选择github)创建一个目录config-repo用于存放配置文件。然后在目录里放置配置文件(我放置了一个微服务的3重环境的配置文件做示例)
client-dev.yml
env: dev
client-test.yml
env: test
client-prod.yml
env: prod
因为配置中心管理者很多的配置文件,所以配置文件的命名方式为:
分支(默认master)+应用名+环境变量(profile)
在服务注册与发现(Eureka)一文中我们为eureka创建了一个client端,现在把他改造成config的server端。
1.在pom文件中引入依赖
org.springframework.cloud
spring-cloud-config-server
2.添加配置文件信息
server:
port: 38762 #服务端口
spring:
application:
name: config-server #服务名称
cloud:
config:
server:
git:
uri: https://gitee.com/fitzMeng/config-repo #git仓库
username: [email protected] #账号
password: ******** #密码
basedir: ./config #本地存放文件夹
eureka:
client:
service-url:
defaultZone: http://localhost:38761/eureka/ #eureka服务端的地址
3.启动类添加@EnableConfigServer
@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigServer
@Slf4j
public class ConfigserverApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigserverApplication.class, args);
log.info("ConfigserverApplication启动");
}
}
4.启动应用,访问localhots:38762/client-dev.yml,返回相应的配置信息,说明已经读取到远程仓库里的配置信息
在相应的本地配置文件夹下也已经拉取了最新的配置文件信息
至此服务配置中心已经创建成功。
我们可以通过访问配置信息的URL与配置文件的映射关系,获取相应的配置
/{application}/{profile}[/{label}]/{application}-{profile}.yml/{label}/{application}-{profile}.yml/{application}-{profile}.properties/{label}/{application}-{profile}.properties
URL会映射{application}-{profile}.yml(或者properties)。{label}对应于git上的不同分支,默认为master。
1.创建一个名为api-gateway的模块(网关模块,后续会进行相关介绍)。然后引入依赖
org.springframework.cloud
spring-cloud-starter-config
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
这里引入了2个依赖分别为Eureka的客户端依赖,一个是服务配置中心的客户端依赖。
2.添加配置文件信息
server:
port: 38763 #端口号
spring:
application:
name: api-gateway #服务名称
cloud:
config:
discovery:
enabled: true
service-id: CONFIG-SERVER #服务配置中心应用名称
profile: dev #开发环境
eureka:
client:
service-url:
defaultZone: http://localhost:38761/eureka/ #eureka服务端的地址
然后在远程git仓库创建一个名为apt-gateway-dev.yml的文件,文件内容为
env: dev
然后启动api-gateway应用,会看到控制台报错
2019-10-26 21:59:54.529 INFO 7372 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://localhost:88882019-10-26 21:59:55.642 INFO 7372 --- [ main] c.c.c.ConfigServicePropertySourceLocator : Connect Timeout Exception on Url - http://localhost:8888. Will be trying the next url if available
从控制台可以看到,该应用是向http://localhost:8888获取配置文件信息,而服务配置文件是http://localhost:38761。这个错误就牵扯到spring boot启动加载顺序的问题。如果都是application.yml(application.properties),服务就会在获取到config服务端信息之前就会去获取配置文件,没有获取到config服务端的信息,自然使用默认的配置。所以将程序里的配置文件名改成bootstrap.properties(优先级高于application.yml)。
3.编写一个控制层,利用@Value检验一下
@RestController
public class EnvController {
@Value("${env}")
private String env;
@GetMapping("/env")
public String getEnv(){
return env;
}
}
启动服务,浏览http://localhost:38763/env,可以看到打印出git仓库的配置信息
至此,一个简单的从远程仓库获取配置文件的实例就完成了,但当你修改了远程仓库的配置文件,在修改后刷新页面,你会发现相应的参数值是没有变的,还是原来的值。这是因为配置文件是在启动时加载,虽然远程仓库进行了修改,但服务并不知道参数已经被修改,不会自动更新自己的配置。怎么在远程仓库修改之后,是开启的服务自动获取更改后的值,将会在下一篇分布式配置中心的服务化及动态刷新中介绍。
本篇主要是spring cloud config的一些常规使用,需要注意的坑主要是在config的client端配置文件的加载的顺序需要加以注意以及eureka的注册地址需要放在config的前置配置文件(bootstrap.properties)中,不能放在远程仓库的配置文件里。至于配置文件的动态刷新和实时生效,会在下一篇文章中进行介绍。本文主要使用了git仓库做示例,感兴趣的同学可以试试其他的,比如svn或者本地资源库的形式。