• 周五. 8月 19th, 2022

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

[zebra源码]分组数据源GroupDataSource及其初始化

admin

11月 28, 2021

GroupDataSource 负责一组 db节点,包含多个SingleDataSource, 将它们分为一个主和多个从进行读写分离和多个从库的负载均衡; 对应db部署架构的话 对应一个分库 或 一主多从

shardDataSource分库分表中的分库对应的就是 GroupDataSource,也可单独读写分离、负载均衡使用

初始化过程 GroupDataSource#init()

public synchronized void init() {
	if (StringUtils.isBlank(jdbcRef)) {
		throw new ZebraException("jdbcRef cannot be empty");
	}

	this.checkJdbcRefInitializationTimes();

	if (init) {
		throw new ZebraException(String.format("GroupDataSource [%s] is already initialized once.", jdbcRef));
	} else {
		this.init = true;
	}

	try {
	             // 权限检查,根据配置判断当前应用是否有db的访问权限
		this.securityCheck();
		// 初始化配置相关的组件
		this.initConfig();
		// 加载自定义jdbcFilter过滤器
		this.initFilters();
		// 逐个执行jdbcFilter过滤器 initGroupDataSource
		if (filters != null && filters.size() > 0) {
			JdbcFilter chain = new DefaultJdbcFilterChain(filters) {
				@Override
				public void initGroupDataSource(GroupDataSource source, JdbcFilter chain) {
					if (index < filters.size()) {
						filters.get(index++).initGroupDataSource(source, chain);
					} else {
						// 开始初始化
						source.initInternal();
					}
				}
			};
			chain.initGroupDataSource(this, chain);
		} else {
			// 开始初始化
			initInternal();
		}

		// 记录下启动次数
		this.recordJdbcRefInitializationTimes();
	} catch (Exception e) {
		String errorMsg = "init GroupDataSource[" + jdbcRef + "] error!";
		LOGGER.error(errorMsg, e);
		throw new ZebraException(errorMsg, e);
	}
}

开始初始化 #initInternal()

protected void initInternal() {
	// 初始化 SingleDataSource 单数据的源管理器
	// 启动监控线程任务 CloseDataSourceTask, 不断轮训待关闭的SingleDataSource(配置刷新后 老的ds或者主动关闭的ds)
	SingleDataSourceManagerFactory.getDataSourceManager().init();
	// 初始化主库和从库的SingleDataSource
	initDataSources();
	// 初始化读写策略,可以强指定读master
	initReadWriteStrategy();
	// 将GroupDataSource自身加入到 配置刷新列表中,每隔60秒会检查一次配置,如果发生变更的话会重新拉取配置 重建sds
	DataSourceConfigRefresh.getInstance().register(this);
	LOGGER.info(String.format("GroupDataSource(%s) successfully initialized.", jdbcRef));
}

#initDataSource(); 初始化数据源,会将读写数据源单独初始化

private void initDataSources() {
	try {
		// 初始化读库数据源,连接获取的时候读库间根据权重负载均衡 选择SingleDataSource
		this.**readDataSource** = new LoadBalancedDataSource(getLoadBalancedConfig(groupConfig.getDataSourceConfigs()),
		      this.filters, systemConfigManager.getSystemConfig(), this.configManagerType, this.configService,
		      groupConfig.getRouterStrategy());
		this.readDataSource.init();
		// 初始化写库(master)数据源 快速失败
		this.**writeDataSource** = new FailOverDataSource(getFailoverConfig(groupConfig.getDataSourceConfigs()),
		      this.filters);
		this.writeDataSource.init();
	} catch (RuntimeException e) {
		try {
			this.close(this.readDataSource, this.writeDataSource);
		} catch (SQLException ignore) {
		}

		throw new ZebraException("fail to initialize group dataSource [" + jdbcRef + "]", e);
	}
}
  • LoadBalancedDataSource 也是实现了DataSource的,它包裹分组内所有从库的 SingleDataSource 根据负载策略选取 sds
  • FailOverDataSource 同样实现了DataSource,它包裹写库的 SingleDataSource

这两个算是装饰模式

完整目录:数据库中间件zebra源码分析

本文来自博客园,作者:mushishi,转载请注明原文链接:https://www.cnblogs.com/mushishi/p/15022066.html

发表回复

您的电子邮箱地址不会被公开。