Spring Cloud 高可用配置中心 数据库方式 Config Server

SpringBoot 版本2.1.4.RELEASE、Spring Cloud版本Greenwich.RELEASE

注:本文的配置中心均指配置中心服务端

1. 配置中心介绍

Spring Cloud Config为分布式系统中的外部配置提供服务器和客户端支持。使用Config Server,您可以在所有环境中管理应用程序的外部属性。客户端和服务器上的概念映射与Spring Environment和PropertySource抽象相同,因此它们与Spring应用程序非常契合,但可以与任何以任何语言运行的应用程序一起使用。随着应用程序通过从开发人员到测试和生产的部署流程,您可以管理这些环境之间的配置,并确定应用程序具有迁移时需要运行的一切。服务器存储后端的默认实现使用git,因此它轻松支持标签版本的配置环境,以及可以访问用于管理内容的各种工具。可以轻松添加替代实现,并使用Spring配置将其插入。
更多相关配置中心配置请查看:https://springcloud.cc/spring-cloud-config.html

2、配置中心服务端代码

2.1、maven依赖

2.1.1、 pom代码

<!--eureka client可以将服务注册到 eureka server -->
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
	</dependency>
	<!-- 配置中心-->
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-config-server</artifactId>
	</dependency>
	<!-- 属性配置使用jdbc,数据库配置 -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-jdbc</artifactId>
	</dependency>
	<!-- mysql数据库存储属性-->
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
	</dependency>
	<!-- 设置接口返回的格式为xml、xml的优先级高于json -->
	<dependency>
		<groupId>com.fasterxml.jackson.jaxrs</groupId>
		<artifactId>jackson-jaxrs-xml-provider</artifactId>
	</dependency>
	<!-- 配置安全机制、只有经过验证的服务才可以注册到服务中心 -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-security</artifactId>
	</dependency>

2.1.2、 依赖说明

2.1.2.1、 设置返回数据的格式

配置中心web返回数据默认为json,且是没有经过格式化的json,不便于观察,可引入jackson-jaxrs-xml-provider包,将返回的数据格式设置为xml方式,查看更加直观,如下图所示:

springcloud yml mysql集群 springcloud连接mysql_spring

2.1.2.2 设置配置中心安全性

为防止配置中心的数据泄露,可以配置账号密码进行拦截,只有登录后,才能看到配置中心的数据。可以添加spring-boot-starter-security依赖。

springcloud yml mysql集群 springcloud连接mysql_数据库_02

2.1.2.3 数据库依赖MySQL

数据库依赖使用mysql,也可以使用其他类型数据库。新建一个数据库sc,在数据库中创建表properties。

DROP TABLE IF EXISTS `properties`;
CREATE TABLE `properties` (
  `id` varchar(32) COLLATE utf8_bin NOT NULL,
  `key` varchar(50) COLLATE utf8_bin NOT NULL,
  `value` varchar(500) COLLATE utf8_bin NOT NULL DEFAULT '',
  `application` varchar(1000) COLLATE utf8_bin NOT NULL,
  `profile` varchar(50) COLLATE utf8_bin NOT NULL,
  `label` varchar(50) COLLATE utf8_bin NOT NULL,
  `remark` varchar(1000) COLLATE utf8_bin DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

id可以随意设置,可以设置为自增。
key为属性名
value为属性值
application为服务/应用名,名称中不能含有下划线_,可以含有中划线。
profile为环境属性,如:dev,test,也可以随意设置,主要用于区分不同环境。
label即为标签
remark为注释,用于解释每一个属性的含义,不然后期维护的属性多了,可能自己都不知道配置的属性的含义

注:表中的id和remark为非必须的字段

数据库表如下图所示:

springcloud yml mysql集群 springcloud连接mysql_数据库方式配置_03

2.2、配置文件(bootstrap.properties)

2.2.1、配置文件代码

server.port=9010

eureka.server.node1=localhost:9000
eureka.server.node2=localhost:9001
spring.security.user.name=admin
spring.security.user.password=1111
#properties表所在的数据库连接url
spring.datasource.url=jdbc:mysql://localhost:3306/sc
#数据库用户名
spring.datasource.username=root
#数据库密码
spring.datasource.password=123456

#jdbc方式的配置中心
spring.profiles.active=jdbc
spring.security.user.roles=SUPERUSER

eureka.instance.prefer-ip-address=true
spring.application.name=config-server
eureka.instance.instance-id=${spring.application.name}:${server.port}
eureka.client.service-url.defaultZone=http://${spring.security.user.name}:${spring.security.user.password}@${eureka.server.node1}/eureka/,http://${spring.security.user.name}:${spring.security.user.password}@${eureka.server.node2}/eureka/

#根据application、profile、label查询key、value
spring.cloud.config.server.jdbc.sql=SELECT `KEY`, `VALUE` from PROPERTIES where position(? in APPLICATION) and PROFILE=? and LABEL=?
#数据库驱动
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#心跳超时时间,如果超过时间没有续约,则从注册中心删除
eureka.instance.lease-expiration-duration-in-seconds=2
#实例续约频率,故改值必须小于eureka.instance.lease-expiration-duration-in-seconds
eureka.instance.lease-renewal-interval-in-seconds=1

#允许应用程序通过在远程存储库中设置标志spring.cloud.config.overrideNone=true(默认值为false),在环境变量或系统属性中提供自己的值
spring.cloud.config.override-none=true

2.2.2、配置说明

2.2.2.1、属性查询:

默认查询语句为:SELECT KEY, VALUE from PROPERTIES where APPLICATION=? and PROFILE=? and LABEL=?

但是这样无法共用一些属性,例如应用A和应用B需要配置相同的数据库(即数据库配置相同),则需要将数据库配置多次。但是经过修改后,只需要在application字段加个应用名就行。如下图所示:

springcloud yml mysql集群 springcloud连接mysql_数据库_04


如果后期数据库有改动,也可以将配置分开,每一应用创建一份数据库配置。

如修改后的sql:spring.cloud.config.server.jdbc.sql=SELECT KEY, VALUE from PROPERTIES where position(? in APPLICATION) and PROFILE=? and LABEL=?

profile默认为default,label默认为master

2.2.2.2、配置中心储存类型设置

使用那种类型作为配置中心的储存方式,可以设置:spring.profiles.active=jdbc
储存方式还有其他类型,如subversion、git、jdbc、native、vault等方式。甚至可以使用组合的方式,配置如下:

spring.profiles.active=git, svn
spring.cloud.config.server.svn.uri=file:///path/to/svn/repo
spring.cloud.config.server.svn.order=2
spring.cloud.config.server.git.uri=file:///path/to/git/repo
spring.cloud.config.server.git.order=1

除了指定URI的每个repo之外,还可以指定order属性。order属性允许您指定所有存储库的优先级顺序。order属性的数值越低,优先级越高。存储库的优先顺序将有助于解决包含相同属性的值的存储库之间的任何潜在冲突。任何一中配置和出错,会导致应用无法启动

甚至可以自定义组合环境:
实现EnvironmentRepository、Ordered接口,如果不实现Ordered接口,自定义的环境将设置为最低优先级。

2.3、配置中心启动

@EnableEurekaClient
@EnableConfigServer
@SpringBootApplication
public class ConfigServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(ConfigServerApplication.class, args);
	}
}

3、配置中心启动

传入不同的端口启动即可:

java -jar config-server.jar --server.port=9010

java -jar config-server.jar --server.port=9011

启动完成,注册中心如下图所示:

springcloud yml mysql集群 springcloud连接mysql_spring_05


配置中心查询sc-portal应用属性如下图所示:

springcloud yml mysql集群 springcloud连接mysql_高可用配置中心_06

3、配置中心客户端代码

spring.cloud.config.username=admin
spring.cloud.config.password=1111
spring.cloud.config.discovery.service-id=config-server
spring.cloud.config.discovery.enabled=true
spring.cloud.config.profile=dev
spring.cloud.config.label=schema

maven依赖,不用添加注解

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

因为配置中心的服务端只有经过账号、密码登陆授权之后才能访问,故spring.cloud.config.username和spring.cloud.config.password就是配置登入配置中心的账号和密码。注意:spring.cloud.config.username和spring.security.user.name含义不同。spring.security.user.name是登陆当前应用的账号

高可用配置中心和单机版配置中心(客户端)配置最关键的就是配置中心服务器的配置,高可用配置中心配置的是服务id(spring.cloud.config.discovery.service-id,默认为configserver),而单机版配置中心配置的是url(spring.cloud.config.uri,默认为http://localhost:8888),虽然高可用配置的是服务id,但是在请求配置中心的应用属性的时候,还是会从注册中心服务列表中取最后一个注册的配置中心应用的url,然后再请求,高可用的配置中心服务器可以只配一个。
所以任何时候,将配置中心配置成高可用的形式,是最佳的选择,这样就算只启动一个配置中心也不影响,如果后面再扩展,再动态添加即可。

将serviceId转化为uri的操作可见:
DiscoveryClientConfigServiceBootstrapConfiguration —> refresh()方法,关键代码如下

List<ServiceInstance> serviceInstances = this.instanceProvider.getConfigServerInstances(serviceId);

配置中心客户端请求服务端接口代码位置:

ConfigServicePropertySourceLocator ---> locate() ---> getRemoteEnvironment()

如果是高可用的配置中心,则ConfigClientProperties配置属性uri.length >= 1,getRemoteEnvironment方法会根据uri依次请求配置中心服务器,一旦能正常返回,则不再请求。

故配置中心有两个配置高可用的方式:

1、通过serviceId,但最终还是将serviceId转为uri,可以动态扩展(推荐)
spring.cloud.config.discovery.service-id=config-server
spring.cloud.config.discovery.enabled=true
先请求后注册的配置中心,如9010端口先注册,9011端口后注册,则先请求9011端口配置中心
2、通过配置url,不能动态添加,多个之间逗号分隔
spring.cloud.config.uri=http://localhost:9010,http://localhost:9011
先请求放在前面的配置中心,如:http://localhost:9010