概念

对于微服务系统来说,一个系统内可能有几十个服务,然后可能会启动上百个实例。
可能其中十个服务都需要连接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.ymlhttp://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访问规则

根据最后一个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动态刷新]

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐