美文网首页Java
[zebra源码]分组数据源GroupDataSource及其初

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

作者: holysu | 来源:发表于2021-04-28 11:02 被阅读0次

    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源码]分组数据源GroupDataSource及其初

        本文链接:https://www.haomeiwen.com/subject/ovqvrltx.html