概念
对于微服务系统来说,一个系统内可能有几十个服务,然后可能会启动上百个实例。
可能其中十个服务都需要连接DB,二十个服务都需要连接Redis或者MQ。如果把DB连接url及用户名密码分写配置到各个服务的application.yml文件中,将会是一件十分枯燥和容易出错的事情,而且如果DB库更换用户名了话,需要各个服务一个一个去修改然后重启,显然是非常不合理的。
在微服务系统中,把配置统一放到配置中心服务,然后各个服务到配置中心拉取配置。当配置修改后,可以通过bus总线通知各个服务,使其从配置中心拉取修改后的配置。
springCloud Config配置中心
先创建并启动一个配置中心服务:
1,创建一个maven项目scd-config-server
项目名称可以按需自定义
2,引入pom依赖
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-parent -->
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Greenwich.RELEASE</version>
</parent>
<groupId>com.scd</groupId>
<artifactId>scd-config-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>scd-config-server</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<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-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- parent指定为spring-cloud-starter-parent,可以自动管理springBoot和其它依赖的version
- 配置中心服务需要引入spring-cloud-config-server
- 其作为一个eureka客户端,需要引入spring-cloud-starter-netflix-eureka-client
- spring-boot-maven-plugin为springboot项目的打包plugin
3,启动类上加@EnableConfigServer注解
@SpringBootApplication
@EnableConfigServer
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
4,加上application.yml配置
spring:
application:
name: scd-config-server
profiles:
active:
- native #使用本地配置
cloud:
config:
server:
native:
search-locations:
- classpath:config-repo/ # 搜索src/main/resource 下的config-repo文件夹下的文件
# git配置
# git:
# uri: https://gitee.com/ifrozen/spring-cloud-demo
# search-paths:
# - config-repo
# username: username
# password: password
#---------------------------------------------------------------------
server:
port: 50010
#---------------------------------------------------------------------
eureka:
instance:
prefer-ip-address: true
status-page-url-path: /actuator/info
health-check-url-path: /actuator/health
hostname: localhost
client:
register-with-eureka: true #把本服务也注册到注册中心,从注册中心的服务列表中可以看到本服务
fetch-registry: true #从注册中心拉取服务列表
service-url:
defaultZone: http://localhost:50000/eureka/
- spring.profiles.active指定为native,代表使用本地配置作为配置仓库,为了演示方便,我们的示例采用本地配置。但是正式环境中推荐使用git来作为配置仓库。
- spring.cloud.config.server.xxx是用来设置配置仓库的:
- native表示本地,search-locations来指定仓库目录
- 其它仓库可以使git,svn等
5,创建配置仓库
在上面一步中设置了spring.cloud.config.server.native.search-locations为classpath:config-repo/ ,即仓库位置为src/main/resource 下的config-repo文件夹
我们创建scd-biz-smile-dev.yml,scd-biz-smile-test.yml,scd-biz-smile-prod.yml三个配置文件,分别代表调试,测试和正式环境的配置文件。
里面只有一个属性smile,值分别为dev,test,prod。例scd-biz-smile-dev.yml
smile: dev
完整示例代码可以参照:https://gitee.com/ifrozen/spring-cloud-demo/tree/master/demo-2
6,访问配置仓库
启动配置中心服务,访问 http://localhost:50000/ 可以看到配置中心服务的启动状况:
访问 http://localhost:50010/config-repo/scd-biz-smile-dev.yml 可以看到:
分别访问 http://localhost:50010/config-repo/scd-biz-smile-test.yml 和 http://localhost:50010/config-repo/scd-biz-smile-prod.yml 可以看到 smile: test 和 smile: prod
标签定义:
- 配置仓库的目录为{label}:本例中为 config-repo
- 文件名称最后一个 - 符号前面的为{name}:本例中为 scd-biz-smile
- 文件名称最后一个 - 符号后面的为{profile}:本例中为 dev,test,prod
url访问规则:
- http://ip:port/{label}/{name}-{profile}.yml
- http://ip:port/{name}-{profile}.yml
- http://ip:port/{label}/{name}-{profile}.properties
- http://ip:port/{name}-{profile}.properties
- http://ip:port/{name}/{profile}[/{label}]
根据最后一个url规则,可以看到访问 http://localhost:50010/scd-biz-smile/dev/config-repo 也是可以的,返回结果为:
{
"name":"scd-biz-smile",
"profiles":[
"dev"
],
"label":"config-repo",
"version":null,
"state":null,
"propertySources":[
{
"name":"classpath:config-repo/scd-biz-smile-dev.yml",
"source":{
"smile":"dev"
}
}
]
}
springCloud Config客户端
配置中心服务创建启动后,我们的其它服务需要从其上面拉取配置,创建并启动一个普通服务:
1,创建一个maven项目scd-biz-smile
项目名称可以按需自定义
2,引入pom依赖
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-parent -->
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Greenwich.RELEASE</version>
</parent>
<groupId>com.scd</groupId>
<artifactId>scd-biz-smile</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>scd-biz-smile</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>
spring-cloud-starter-netflix-hystrix
</artifactId>
</dependency>
<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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- parent指定为spring-cloud-starter-parent,可以自动管理springBoot和其它依赖的version
- 配置中心客户端需要引spring-cloud-starter-config
- 其作为一个eureka客户端,需要引入spring-cloud-starter-netflix-eureka-client,spring-cloud-starter-netflix-hystrix
- 对外提供rest接口,作为一个web服务需要引入spring-boot-starter-web
- spring-boot-maven-plugin为springboot项目的打包plugin
3,启动类,普通的SpringCloudApplication启动类即可
@SpringCloudApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
创建一个普通controller类读取配置文件中的smile属性:
@RestController
public class SmileController {
@Value("${smile}")
private String smile;
@GetMapping("/config")
public String config() {
return smile;
}
}
- @Value是springboot的注解,可以从yml配置文件中读取配置
4,yml配置文件
由于从配置中心拉取配置仓库要先于其它功能的启动,其它功能才能读取到配置。
所以配置文件需要增加一个bootstrap.yml,spring启动的时候,会先读取bootstrap.yml的配置来启动,然后再读取application.yml的配置来启动。
使用配置中心后,客户端服务的eureka配置和config配置必须写到bootstrap.yml里面去,其它配置可以写到application.yml里面去。
bootstrap.yml
spring:
cloud:
config:
discovery:
enabled: true
service-id: scd-config-server
label: config-repo
name: scd-biz-smile
profile: dev
#---------------------------------------------------------------------
eureka:
instance:
prefer-ip-address: true
status-page-url-path: /actuator/info
health-check-url-path: /actuator/health
hostname: localhost
client:
register-with-eureka: true #把本服务也注册到注册中心,从注册中心的服务列表中可以看到本服务
fetch-registry: true #从注册中心拉取服务列表
service-url:
defaultZone: http://localhost:50000/eureka/
- spring.cloud.config.discovery.enabled用来开启配置中心
- spring.cloud.config.discovery.service-id指定配置中心服务
- spring.cloud.config.label对应配置仓库的目录,本例中为 config-repo
- spring.cloud.config.name对应配置文件名称最后一个 - 符号前面的名称,本例中为 scd-biz-smile
- spring.cloud.config.profile对应配置文件名称最后一个 - 符号后面的名称,本例中为 dev
application.yml
spring:
application:
name: scd-biz-smile
#---------------------------------------------------------------------
server:
port: 50020
servlet:
context-path: /smile
#---------------------------------------------------------------------
- server.servlet.context-path为项目名
完整示例代码可以参照:https://gitee.com/ifrozen/spring-cloud-demo/tree/master/demo-2
启动服务后,可以现在 http://localhost:50000/ 查看服务启动情况:
访问 http://localhost:50020/smile/config rest接口:
至此一套配置中心服务于客户端已经搭建完成。
但是还有另一个问题,如果配置仓库的属性变更了,比如说我们把scd-biz-smile-dev.yml的值改为:
smile: dev-update
然后不重启scd-biz-smile服务,直接访问 http://localhost:50020/smile/config rest接口,发现返回的还是变更前的dev,怎么样才能不重启服务,让其能获取到变更后的值呢,请看下一章 [3:SpringCloud Config配置中心的bus动态刷新]