0 前言

对系统中存在的各服务和资源进行统一治理,ShardingSphere也集成了编制治理的功能。咋用 ShardingSphere提供的编排治理功能进行展开:

  • 先讨论 ShardingSphere 对编排治理的抽象过程
  • 再给出开发过程中,基于配置中心介绍集成编排治理功能的系统改造方案

ShardingSphere咋抽象编排治理?与开发紧密相关的是其配置中心、注册中心功能。

1 ShardingSphere的配置中心

配置信息管理,常存于YAML或XML格式的配置文件,完成配置信息的维护,ShardingSphere都支持:

  • 单体系统,配置文件即可,配置管理工作轻松
  • 分布式系统,越来越多运行时实例,使得散落配置难管,配置数据不同步导致的问题十分严重。将配置集中于配置中心,可更有效管理

采用配置中心,即采用集中式配置管理设计思想:

  • 开发、测试和生产等不同环境配置信息统一保存在配置中心
  • 需确保分布式集群中同类服务的所有服务实例保存同一份配置文件,且能同步更新

ShardingSphere提供多种配置中心实现如zk、Etcd、Apollo和Nacos。也可自定义配置中心通过SPI加载到ShardingSphere运行时环境中。

配置信息不是一成不变。对修改后的配置信息的统一分发,是配置中心可提供的另一重要能力。配置中心中配置信息的任何变化都可以实时同步到各个服务实例中。ShardingSphere通过配置中心可支持数据源、数据表、分片及读写分离策略的动态切换。

基于集中式配置信息管理方案,ShardingSphere也支持本地加载配置信息。若希望以本地配置为准,并将本地配置覆盖配置中心配置,通过开关即可。

2 ShardingSphere的注册中心

实现类似注册中心与配置中心,ShardingSphere也提供基于zk、Etcd的注册中心实现方案,而他俩同样也可被用作配置中心。

2.1 注册中心 V.S 配置中心

不同在于保存的数据类型:

  • 配置中心管理的配置数据
  • 注册中心存放 ShardingSphere 运行时各种动态/临时状态数据,最典型运行时状态数据就是当前的 Datasource 实例

2.2 为啥保存动态和临时状态数据?

注册中心的数据存储和监听:

注册中心都提供分布式协调机制。注册中心的所有 DataSource 在指定路径根目录创建临时节点,所有访问这些 DataSource 的业务服务都会监听该目录:

  • 新 DataSource 加入,注册中心实时通知到所有业务服务,由业务服务做相应路由信息维护
  • 某 DataSource 宕机,业务服务通过监听机制也会收到通知

基此,就可提供针对 DataSource 的治理能力,如:

  • 熔断对某 DataSource 的数据访问
  • 禁用对从库 DataSource 的访问

ShardingSphere注册中心更多面向框架内部,普通场景无需过多了解注册中心使用方法。ShardingSphere针对注册中心所打造的面向开发的功能有限。因此,本文关注配置中心使用。

3 集成配置中心

3.1 准备环境

① 编排治理

为集成配置中心,先引入ShardingSphere中与编排治理相关的依赖包:

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-orchestration-spring-boot-starter</artifactId>
    <version>4.1.1</version>
</dependency>

② zk

ShardingSphere集成的zk客户端组件是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

对应也有 DataSourceFactory 工厂类。

治理规则配置类OrchestrationConfiguration,其他 DataSourceFactory 所用也是这配置类:

public final class OrchestrationConfiguration {
    // 治理规则名称
    private final String name;
    // 注册(配置)中心配置子类
    private final RegistryCenterConfiguration regCenterConfig;
    // 本地配置是否覆写服务器配置标志位
    private final boolean overwrite;
}

RegistryCenterConfiguration包最常见最通用的部分配置项:

public final class RegistryCenterConfiguration extends TypeBasedSPIConfiguration {

    // 配置中心服务器列表
    private String serverLists;   
    // 命名空间
    private String namespace;
       …
}

实现基于zk的配置中心

先下载zk服务器组件,并确保启动成功。如采用默认配置,zk会在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
=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

3.3 指定配置中心

=health_ms
# 即前面的这些本地配置项会覆盖保存在zk服务器的配置项,即采用本地配置模式
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

启动服务,与zk通信的相关日志:

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

zk服务器端也对来自应用程序的请求作出响应。可用一些zk可视化客户端工具来观察目前服务器上的数据。使用ZooInspector,由于zk本质是树状结构,所以在根节点新增配置信息:ZooKeeper 中的配置节点图

关注“config”段内容,其中“rule”节点包含了读写分离的规则设置:

ZooKeeper 中的“rule”配置项

“datasource”节点包含的显然是前面所指定的各个数据源信息。

服务器端配置,进而影响到所有使用这些配置的应用程序。如果不希望产生这种影响,而是统一使用位于配置中心上的配置,咋办?只需将 spring.shardingsphere.orchestration.overwrite 设置为 false 即可。将这个配置开关进行关闭,意味着我们将只从配置中心读取配置,也就是说,本地不需要保存任何配置信息,只包含指定配置中心相关内容:

=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:

=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=

4 总结

讨论 ShardingSphere 中与编排治理相关的功能支持。ShardingSphere 提供了配置中心和注册中心两种治理机制,这两种机制采用了类似的底层设计,但面向不同的应用场景。我们结合案例,基于配置中心给出了具体的开发过程。对于配置中心而言,重点是需要理解如何基于 Zookeeper 这个分布式协调工具来完成本地和远程配置信息之前的动态更新和同步

FAQ

ShardingSphere的配置中心和注册中心在设计上有哪些相同点和不同点?

只要配置信息变化时能够实时更新,spring.shardingsphere.orchestration.overwrite设置为true和false有啥区别呢?

这个标志位决定是是否需要把本地的配置覆盖服务器上配置。

Q:使用nacos界面创建配置信息,文件名(dataID)需要和啥对应?

A:Data ID = {spring.profiles.active} + .文件后缀

Q:nacos配置中心,shardingsphere咋找到配置中心的配置文件?配置文件名字是啥?

A:nacos内部存储方式对开发透明,ShardingSphere通过nacos的客户端API来获取其中的配置信息

Q:配置中心理解为 配置文件的统一管理。注册中心 是可以管理 接入shardingSphere的系统的运行时态管理?那shardingSphere集群是关于ShardingSphere中所有管理的数据库实例的运行时状态?

A:你的理解基本是对的。以下将详细说明 配置中心注册中心 的作用,并结合 ShardingSphere 的运行时管理来分析:


配置中心与注册中心的作用

  1. 配置中心

    • 核心功能:用于统一管理静态配置,便于分布式系统中配置的集中式管理和动态更新。
      • 例如:数据库连接信息、服务调用地址等。
    • 适用场景
      • 配置文件繁多,分布式环境下需要集中管理和动态推送。
      • 服务运行时只需要获取固定的配置,不需要频繁更新。
  2. 注册中心

    • 核心功能:用于动态服务发现和运行时状态管理。
      • 例如:记录当前有哪些服务实例上线或下线、服务运行时健康状态等。
    • 适用场景
      • 微服务架构中服务动态扩缩容。
      • 服务间需要实时更新运行状态(如健康检查、负载均衡)。

ShardingSphere 的配置中心与注册中心

ShardingSphere 的架构中,配置中心和注册中心的用途更加明确,分别管理静态配置和动态运行状态:

1. 配置中心

  • 功能
    • 存储 ShardingSphere 规则配置(如分片规则、读写分离规则)。
    • 存储数据源配置(包括各个数据库实例的连接信息)。
  • 目标:统一管理分布式数据库的静态配置,避免频繁修改配置文件。
  • 示例
    • 通过配置中心,你可以将规则配置存储到 Zookeeper、Etcd 或者 Nacos 等外部工具,便于动态更新。

2. 注册中心

  • 功能
    • 记录和管理接入 ShardingSphere 的所有数据库实例的运行时状态。
    • 包括实例的在线/离线、健康状态、分布式协调任务的调度等。
  • 目标:动态管理分布式数据库实例的运行状态,支持负载均衡和高可用性。
  • 示例
    • 某个数据库实例故障下线,注册中心会感知并通知集群重新分配任务。

ShardingSphere 集群的运行时状态

ShardingSphere 集群确实是关于所有管理的数据库实例的运行时状态。以下是具体细节:

1. 实例运行状态

  • 健康检查:定期检查数据库实例的健康状态(如网络连接、存活状态)。
  • 动态上下线:实例上线或下线会动态通知集群,触发重新分片或切换数据源。

2. 分布式任务协调

  • 在分布式环境中,ShardingSphere 需要协调多个实例的任务调度,例如分布式事务、分片计算。
  • 注册中心会记录分布式任务的执行状态,确保任务不会重复或遗漏。

3. 配置与状态的联动

  • 当实例状态变化时(如实例故障),ShardingSphere 会通过注册中心感知,调整数据分片规则或读写分离策略。

总结

  • 配置中心 是用于管理 ShardingSphere 的静态配置,例如分片规则、数据源信息等,作用类似于 "配置文件的统一管理"。
  • 注册中心 则用于动态管理数据库实例的运行时状态,确保分布式环境中的协调与高可用性。
  • ShardingSphere 集群 涉及的运行时状态,正是由注册中心统一管理,包括实例状态监控、健康检查以及任务协调。

这两者分工明确,可以各自独立使用,也可以结合起来满足不同的系统需求。

Q:只用配置中心,不用注册中心,运行不会有问题吧?配置中心与注册中心可以不同吗?如配置中心用zookeeper,注册中心用etcd?

只用配置中心,不用注册中心,可以运行,但要看具体的系统架构和功能需求,是否真的需要注册中心。关键参考:

配置中心 V.S 注册中心

  • 配置中心

    • 负责集中管理和分发应用的配置(如数据库连接、服务地址等)。
    • 典型场景:Spring Cloud Config、Apollo、Nacos(也支持配置管理)。
  • 注册中心

    • 负责服务发现和注册,主要用于微服务架构中动态维护服务的健康状态和地址信息。
    • 典型场景:Eureka、Zookeeper、Consul、Nacos。

只用配置中心,不用注册中心

  • 如果你的系统是单体应用静态服务调用(服务地址和端口固定),不依赖动态服务发现,只需要配置中心即可。
  • 缺点:缺乏动态服务发现能力,服务拓扑调整(如扩容/缩容、实例迁移)需要手动更改配置。

配置中心与注册中心可不同吗?

可。配置中心、注册中心功能独立,只要实现了协议或功能要求,技术选型可以不同。例如:

  • 配置中心用 Zookeeper,注册中心用 Etcd。
  • 配置中心用 Apollo,注册中心用 Consul。

配置中心与注册中心混用的注意事项

  1. 技术选型需明确目标

    • 如果使用 Zookeeper,既能作为配置中心又能作为注册中心。
    • Etcd 适合注册中心用途,但原生对配置管理支持不如专用的配置工具。
  2. 性能与一致性

    • 配置中心通常偏重一致性,不需要高频变更。
    • 注册中心可能需要更高性能和实时性,用于高频的服务实例上下线。
  3. 运维复杂度

    • 选型技术不同,可能增加系统维护复杂度(如数据备份、分布式一致性管理)。

实际应用场景建议

  • 如果是初期项目,不需要动态服务发现,仅用配置中心,不使用注册中心,完全可以满足需求。
  • 如果需要动态服务发现,可以考虑将配置中心和注册中心分开,选择各自最擅长的工具(如配置用 Apollo,注册用 Eureka)。

根据你的需求选择合适的工具组合即可,注意两者间的数据一致性和延迟问题即可满足大部分场景需求。

关注我,紧跟本系列专栏文章,咱们下篇再续!

作者简介:魔都架构师,多家大厂后端一线研发经验,在分布式系统设计、数据平台架构和AI应用开发等领域都有丰富实践经验。

各大技术社区头部专家博主。具有丰富的引领团队经验,深厚业务架构和解决方案的积累。

负责:

  • 中央/分销预订系统性能优化
  • 活动&券等营销中台建设
  • 交易平台及数据中台等架构和开发设计
  • 车联网核心平台-物联网连接平台、大数据平台架构设计及优化
  • LLM Agent应用开发
  • 区块链应用开发
  • 大数据开发挖掘经验
  • 推荐系统项目

目前主攻市级软件项目设计、构建服务全社会的应用系统。

参考: