zoukankan      html  css  js  c++  java
  • [zebra源码]分组数据源GroupDataSource及其初始化

    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

  • 相关阅读:
    字符串与字典常用命令
    Python学习之路:字符串常用操作
    Python学习之路:购物车实例
    面试题2017
    c#语法学习
    结构化设计模式-桥接模式
    结构型设计模式-适配器模式
    .Net Cache
    设计模式的六大原则
    uml类图关系
  • 原文地址:https://www.cnblogs.com/mushishi/p/15022066.html
Copyright © 2011-2022 走看看