随着分布式系统和微服务架构的持续发展,对系统中存在的各种服务和资源进行统一治理已经成为系统架构设计过程中的一个基础要点。ShardingSphere 作为一款分布式数据库中间件,同样集成了编制治理方面的功能。
如何使用 ShardingSphere 所提供的编排治理功能进行展开,
- 先讨论 ShardingSphere 对编排治理的抽象过程
- 然后给出在开发过程中,基于配置中心介绍集成编排治理功能的系统改造方案
ShardingSphere 如何抽象编排治理?与日常开发紧密相关的是它的配置中心和注册中心功能。
1 ShardingSphere 中的配置中心
配置信息的管理,常存放在配置文件,可基于 YAML 格式或 XML 格式的配置文件完成配置信息的维护,ShardingSphere 都支持:
- 单体系统中,配置文件能满足需求,围绕配置文件展开的配置管理工作不难
- 分布式系统中,越来越多运行时实例使散落配置难管,且配置不同步导致的问题十分严重。将配置集中于配置中心,可更有效管理
采用配置中心,即意味采用集中式配置管理设计思想:
- 开发、测试和生产等不同环境配置信息统一保存在配置中心内
- 需确保分布式集群中同一类服务的所有服务实例保存同一份配置文件,且能同步更新
ShardingSphere 提供了多种配置中心的实现方案,包括ZooKeeeper、Etcd、Apollo 和 Nacos。开发人员也可以根据需要实现自己的配置中心并通过 SPI 机制加载到 ShardingSphere 运行时环境中。
配置信息不是一成不变。对修改后的配置信息的统一分发,是配置中心可提供的另一重要能力。配置中心中配置信息的任何变化都可以实时同步到各个服务实例中。ShardingSphere 通过配置中心可以支持数据源、数据表、分片以及读写分离策略的动态切换。
集中式配置信息管理方案的基础上,ShardingSphere 也支持从本地加载配置信息。如希望以本地配置信息为准,并将本地配置覆盖配置中心的配置,通过一个开关就可。
2 ShardingSphere 中的注册中心
实现方式,注册中心与配置中心非常类似,ShardingSphere 也提供基于 ZooKeeeper 和 Etcd 这两款第三方工具的注册中心实现方案,而 ZooKeeeper 和 Etcd 同样也可以被用作配置中心。
注册中心与配置中心不同在于两者保存的数据类型:
- 配置中心管理的显然是配置数据
- 但注册中心存放的是 ShardingSphere 运行时的各种动态/临时状态数据,最典型的运行时状态数据就是当前的 Datasource 实例
保存动态和临时状态数据啥用?
注册中心的数据存储和监听机制示意图:
注册中心都提供分布式协调机制。注册中心中,所有 DataSource 在指定路径根目录下创建临时节点,所有访问这些 DataSource 的业务服务都会监听该目录:
- 当有新 DataSource 加入时,注册中心实时通知到所有业务服务,由业务服务做相应路由信息维护
- 当某个 DataSource 宕机时,业务服务通过监听机制同样会收到通知
基于此,就可提供针对 DataSource 的治理能力,如:
- 熔断对某一个 DataSource 的数据访问
- 或禁用对从库 DataSource 的访问
ShardingSphere注册中心更多面向框架内部用,普通场景无需过多了解注册中心使用方法。目前,ShardingSphere 针对注册中心所打造的面向开发人员的功能也还比较有限。因此,本文关注配置中心使用。
3 集成配置中心
3.1 准备环境
① 编排治理相关的依赖包
为集成配置中心,先要引入 ShardingSphere 中与编排治理相关的依赖包。在 Spring Boot 环境中,这个依赖包是 sharding-jdbc-orchestration-spring-boot-starter:
<!-- https://mvnrepository.com/artifact/org.apache.shardingsphere/sharding-jdbc-orchestration-spring-boot-starter -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-orchestration-spring-boot-starter</artifactId>
<version>4.1.1</version>
</dependency>
② 基于 zk 分布式协调工具来实现配置中心
ShardingSphere 中,集成的 ZooKeeeper 客户端组件是 Curator,需引入 sharding-orchestration-reg-zookeeper-curator 组件:
<!-- https://mvnrepository.com/artifact/io.shardingsphere/sharding-orchestration-reg-zookeeper-curator -->
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-orchestration-reg-zookeeper-curator</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
③ 用 Nacos
也需添加相关依赖:
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-orchestration-reg-nacos</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</dependency>
配置好这些之后,开发环境就绪,对于配置中心而言,开发人员主要的工作还是配置。
3.2 掌握配置项
ShardingSphere 提供一系列 DataSource,包括
- 用于数据分片的 OrchestrationShardingDataSource
- 读写分离的 OrchestrationMasterSlaveDataSource
- 数据脱敏的 OrchestrationEncryptDataSource
围绕这些 DataSource,也存在对应 DataSourceFactory 工厂类。
以 OrchestrationMasterSlaveDataSourceFactory 为例来看创建 DataSource 所需要的配置类:
public final class OrchestrationMasterSlaveDataSourceFactory {
public static DataSource createDataSource(final Map<String, DataSource> dataSourceMap, final MasterSlaveRuleConfiguration masterSlaveRuleConfig,
final Properties props, final OrchestrationConfiguration orchestrationConfig) throws SQLException {
if (null == masterSlaveRuleConfig || null == masterSlaveRuleConfig.getMasterDataSourceName()) {
return createDataSource(orchestrationConfig);
}
MasterSlaveDataSource masterSlaveDataSource = new MasterSlaveDataSource(dataSourceMap, new MasterSlaveRule(masterSlaveRuleConfig), props);
return new OrchestrationMasterSlaveDataSource(masterSlaveDataSource, orchestrationConfig);
}
…
}
治理规则配置类 OrchestrationConfiguration,其他 DataSourceFactory 中所使用的也是这配置类:
public final class OrchestrationConfiguration {
//治理规则名称
private final String name;
//注册(配置)中心配置类
private final RegistryCenterConfiguration regCenterConfig;
//本地配置是否覆写服务器配置标志位
private final boolean overwrite;
}
在 OrchestrationConfiguration 中我们看到了用于指定本地配置是否覆写服务器配置的 overwrite 标志位,也看到了一个注册中心的配置子类 RegistryCenterConfiguration。
RegistryCenterConfiguration包最常见最通用的部分配置项:
public final class RegistryCenterConfiguration extends TypeBasedSPIConfiguration {
//配置中心服务器列表
private String serverLists;
//命名空间
private String namespace;
…
}
这里包含了配置中心服务器列表 serverLists 以及用于标识唯一性的命名空间 namespace。因为 RegistryCenterConfiguration 继承了 TypeBasedSPIConfiguration,所以也就自动带有 type 和 properties 这两个配置项。
实现配置中心
实现基于 ZooKeeper 的配置中心。首先需要下载 ZooKeeper 服务器组件,并确保启动成功。如果采用默认配置,那么 ZooKeeper 会在 2181 端口启动请求监听。
创建一个配置文件并输入配置项,由于还是以读写分离为例,因此配置文件设置一主两从一共三个数据源:
spring.shardingsphere.datasource.names=dsmaster,dsslave0,dsslave1
spring.shardingsphere.datasource.dsmaster.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.dsmaster.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.dsmaster.jdbc-url=jdbc:mysql://localhost:3306/dsmaster
spring.shardingsphere.datasource.dsmaster.username=root
spring.shardingsphere.datasource.dsmaster.password=root
spring.shardingsphere.datasource.dsslave0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.dsslave0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.dsslave0.jdbc-url=jdbc:mysql://localhost:3306/dsslave0
spring.shardingsphere.datasource.dsslave0.username=root
spring.shardingsphere.datasource.dsslave0.password=root
spring.shardingsphere.datasource.dsslave1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.dsslave1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.dsslave1.jdbc-url=jdbc:mysql://localhost:3306/dsslave1
spring.shardingsphere.datasource.dsslave1.username=root
spring.shardingsphere.datasource.dsslave1.password=root
spring.shardingsphere.masterslave.load-balance-algorithm-type=random
spring.shardingsphere.masterslave.name=health_ms
spring.shardingsphere.masterslave.master-data-source-name=dsmaster
spring.shardingsphere.masterslave.slave-data-source-names=dsslave0,dsslave1
spring.shardingsphere.props.sql.show=true
指定配置中心
将 overwrite 设置为 true,这意味着前面的这些本地配置项会覆盖保存在 ZooKeeper 服务器上的配置项,也就是说我们采用的是本地配置模式。然后我们设置配置中心类型为 zookeeper,服务器列表为 localhost:2181,并将命名空间设置为 orchestration-health_ms。
spring.shardingsphere.orchestration.name=health_ms
spring.shardingsphere.orchestration.overwrite=true
spring.shardingsphere.orchestration.registry.type=zookeeper
spring.shardingsphere.orchestration.registry.server-lists=localhost:2181
spring.shardingsphere.orchestration.registry.namespace=orchestration-health_ms
启动服务,控制台会出现与 ZooKeeper 进行通信的相关日志信息:
2020-05-30 18:13:45.954 INFO 20272 --- [ main] org.apache.zookeeper.ZooKeeper : Initiating client connection, connectString=localhost:2181 sessionTimeout=60000 watcher=org.apache.curator.ConnectionState@585ac855
2020-05-30 18:13:46.011 INFO 20272 --- [0:0:0:0:1:2181)] org.apache.zookeeper.ClientCnxn : Opening socket connection to server 0:0:0:0:0:0:0:1/0:0:0:0:0:0:0:1:2181. Will not attempt to authenticate using SASL (unknown error)
2020-05-30 18:13:46.012 INFO 20272 --- [0:0:0:0:1:2181)] org.apache.zookeeper.ClientCnxn : Socket connection established to 0:0:0:0:0:0:0:1/0:0:0:0:0:0:0:1:2181, initiating session
2020-05-30 18:13:46.029 INFO 20272 --- [0:0:0:0:1:2181)] org.apache.zookeeper.ClientCnxn : Session establishment complete on server 0:0:0:0:0:0:0:1/0:0:0:0:0:0:0:1:2181, sessionid = 0x10022dd7e680001, negotiated timeout = 40000
2020-05-30 18:13:46.034 INFO 20272 --- [ain-EventThread] o.a.c.f.state.ConnectionStateManager : State change: CONNECTED
ZooKeeper 服务器端也对来自应用程序的请求作出响应。我们可以使用一些 ZooKeeper 可视化客户端工具来观察目前服务器上的数据。
使用 ZooInspector,由于 ZooKeeper 本质上就是树状结构,现在所以在根节点中就新增了配置信息:
关注“config”段内容,其中“rule”节点包含了读写分离的规则设置:
“datasource”节点包含的显然是前面所指定的各个数据源信息。
服务器端配置,进而影响到所有使用这些配置的应用程序。如果不希望产生这种影响,而是统一使用位于配置中心上的配置,咋办?只需将 spring.shardingsphere.orchestration.overwrite 设置为 false 即可。将这个配置开关进行关闭,意味着我们将只从配置中心读取配置,也就是说,本地不需要保存任何配置信息,只包含指定配置中心相关内容:
spring.shardingsphere.orchestration.name=health_ms
spring.shardingsphere.orchestration.overwrite=false
spring.shardingsphere.orchestration.registry.type=zookeeper
spring.shardingsphere.orchestration.registry.server-lists=localhost:2181
spring.shardingsphere.orchestration.registry.namespace=orchestration-health_ms
执行测试用例后,会发现读写分离规则同样生效。
如果你选择使用其他的框架来构建配置中心服务器,比如阿里巴巴的 Nacos,那么也很简单,只需要将 spring.shardingsphere.orchestration.registry.type 设置成 nacos 并提供对应的 server-lists 就可以了:
spring.shardingsphere.orchestration.name=health_ms
spring.shardingsphere.orchestration.overwrite=true
spring.shardingsphere.orchestration.registry.type=nacos
spring.shardingsphere.orchestration.registry.server-lists=localhost:8848
spring.shardingsphere.orchestration.registry.namespace=
总结
讨论 ShardingSphere 中与编排治理相关的功能支持。ShardingSphere 提供了配置中心和注册中心两种治理机制,这两种机制采用了类似的底层设计,但面向不同的应用场景。我们结合案例,基于配置中心给出了具体的开发过程。对于配置中心而言,重点是需要理解如何基于 Zookeeper 这个分布式协调工具来完成本地和远程配置信息之前的动态更新和同步。
FAQ
ShardingSphere 中配置中心和注册中心在设计上有哪些相同点和不同点?
只要配置信息变化时能够实时更新,spring.shardingsphere.orchestration.overwrite设置为true和false有啥区别呢?
这个标志位决定是是否需要把本地的配置覆盖服务器上配置。
使用远程配置中心,比如nacos,工程启动后,修改nacos里面的配置规则,会自动生效吗?我试了下貌似不行。如果想实现该功能,有可行的方案吗
我理解修改配置信息会自动生效的。
使用nacos作为配置中心,你提供的配置报错,找不到数据源,还有一个问题,当我使用nacos界面创建配置信息,文件名(dataID)需要和什么对应上
Data ID = {spring.profiles.active} + .文件后缀
nacos配置中心 shardingsphere怎么找到配置中心的配置文件 配置文件的名字是什么
nacos内部的存储方式对开发人员是透明的,ShardingSphere通过nacos的客户端API来获取其中的配置信息
配置中心理解为 配置文件的统一管理。注册中心 是可以管理 接入shardingSphere的系统的运行时态管理?shardingSphere集群?
关于ShardingSphere中所有管理的数据库实例的运行时状态
1、只用配置中心,不用注册中心,运行不会有问题吧?2、配置中心与注册中心可以不同吗?例如配置中心用zookeeper,注册中心用etcd
配置中心和注册中心都可以只用一个,也都可以使用不同的框架
【文章转自高防服务器 http://www.558idc.com 复制请保留原URL】