zoukankan      html  css  js  c++  java
  • ShardingSphere~2

    功能的注册与配置加载

    以Governance分布式治理的注册中心为例

    代码包整体是按照功能点划分,具体到每个功能,比如治理-代码大致分为spring-boot-starter启动加载相关;context上下文信息定义;core核心执行逻辑,比如对于注册中心,core包含了各类事件,监听的定义,等;api定义了基本的对外交互模型;对于注册中心,不同的实现又具有单独的repository-etcd类似结构目录,结构间的依赖关系源码已经定义好了

    每个主要功能都有对应的启动加载类(sharding/shadow/readwrite/encrypt/db-discovery相同),注册中心起始于shardingsphere-jdbc-governance-spring-boot-starter

    大体逻辑都是通过判断配置文件逻辑是否符合规范,符合则加载配置,创建对应的资源

      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package org.apache.shardingsphere.spring.boot.governance;
     19 
     20 import com.google.common.base.Preconditions;
     21 import lombok.RequiredArgsConstructor;
     22 import org.apache.shardingsphere.driver.governance.internal.datasource.GovernanceShardingSphereDataSource;
     23 import org.apache.shardingsphere.infra.config.RuleConfiguration;
     24 import org.apache.shardingsphere.governance.core.yaml.config.swapper.RegistryCenterConfigurationYamlSwapper;
     25 import org.apache.shardingsphere.governance.repository.api.config.GovernanceConfiguration;
     26 import org.apache.shardingsphere.spring.boot.datasource.DataSourceMapSetter;
     27 import org.apache.shardingsphere.spring.boot.governance.common.GovernanceSpringBootRootConfiguration;
     28 import org.apache.shardingsphere.spring.boot.governance.rule.LocalRulesCondition;
     29 import org.springframework.beans.factory.ObjectProvider;
     30 import org.springframework.beans.factory.annotation.Autowired;
     31 import org.springframework.boot.autoconfigure.AutoConfigureBefore;
     32 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
     33 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
     34 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
     35 import org.springframework.boot.context.properties.EnableConfigurationProperties;
     36 import org.springframework.context.EnvironmentAware;
     37 import org.springframework.context.annotation.Bean;
     38 import org.springframework.context.annotation.ComponentScan;
     39 import org.springframework.context.annotation.Conditional;
     40 import org.springframework.context.annotation.Configuration;
     41 import org.springframework.core.env.Environment;
     42 
     43 import javax.sql.DataSource;
     44 import java.sql.SQLException;
     45 import java.util.Collections;
     46 import java.util.LinkedHashMap;
     47 import java.util.List;
     48 import java.util.Map;
     49 import java.util.Objects;
     50 import java.util.Optional;
     51 
     52 /**
     53  * Governance spring boot configuration.
     54  */
     55 @Configuration
     56 @ComponentScan("org.apache.shardingsphere.spring.boot.converter")
     57 @EnableConfigurationProperties(GovernanceSpringBootRootConfiguration.class)
     58 @ConditionalOnProperty(prefix = "spring.shardingsphere", name = "enabled", havingValue = "true", matchIfMissing = true)
     59 @RequiredArgsConstructor
     60 @AutoConfigureBefore(DataSourceAutoConfiguration.class)
     61 public class ShardingSphereGovernanceAutoConfiguration implements EnvironmentAware {
     62     
     63     private final Map<String, DataSource> dataSourceMap = new LinkedHashMap<>();
     64     
     65     private final GovernanceSpringBootRootConfiguration root;
     66     
     67     private final RegistryCenterConfigurationYamlSwapper swapper = new RegistryCenterConfigurationYamlSwapper();
     68     
     69     /**
     70      * Get governance configuration.
     71      *
     72      * @return governance configuration
     73      */
     74     @Bean
     75     public GovernanceConfiguration governanceConfiguration() {
     76         Preconditions.checkState(Objects.nonNull(root.getGovernance()), "The governance configuration is invalid, please configure governance");
     77         return new GovernanceConfiguration(root.getGovernance().getName(), swapper.swapToObject(root.getGovernance().getRegistryCenter()), root.getGovernance().isOverwrite());
     78     }
     79     
     80     /**
     81      * Get governance ShardingSphere data source bean by local configuration.
     82      *
     83      * @param rules rules configuration
     84      * @param governanceConfig governance configuration
     85      * @return governance sharding data source bean
     86      * @throws SQLException SQL exception
     87      */
     88     @Bean
     89     @Conditional(LocalRulesCondition.class)
     90     @Autowired(required = false)
     91     public DataSource localShardingSphereDataSource(final ObjectProvider<List<RuleConfiguration>> rules, final GovernanceConfiguration governanceConfig) throws SQLException {
     92         List<RuleConfiguration> ruleConfigurations = Optional.ofNullable(rules.getIfAvailable()).orElse(Collections.emptyList());
     93         return createDataSourceWithRules(ruleConfigurations, governanceConfig);
     94     }
     95     
     96     /**
     97      * Get data source bean from registry center.
     98      *
     99      * @param governanceConfig governance configuration
    100      * @return data source bean
    101      * @throws SQLException SQL Exception
    102      */
    103     @Bean
    104     @ConditionalOnMissingBean(DataSource.class)
    105     public DataSource dataSource(final GovernanceConfiguration governanceConfig) throws SQLException {
    106         return createDataSourceWithoutRules(governanceConfig);
    107     }
    108     
    109     @Override
    110     public final void setEnvironment(final Environment environment) {
    111         dataSourceMap.putAll(DataSourceMapSetter.getDataSourceMap(environment));
    112     }
    113     
    114     private DataSource createDataSourceWithRules(final List<RuleConfiguration> ruleConfigs, final GovernanceConfiguration governanceConfig) throws SQLException {
    115         return new GovernanceShardingSphereDataSource(dataSourceMap, ruleConfigs, root.getProps(), governanceConfig);
    116     }
    117     
    118     private DataSource createDataSourceWithoutRules(final GovernanceConfiguration governanceConfig) throws SQLException {
    119         return new GovernanceShardingSphereDataSource(governanceConfig);
    120     }
    121 }
    View Code

    如果是加了@***Condition的,会做逻辑配置逻辑检查

    public final class ReadwriteSplittingSpringBootCondition extends SpringBootCondition {
        
        private static final String PREFIX = "spring.shardingsphere.rules.readwrite-splitting";
        
        @Override
        public ConditionOutcome getMatchOutcome(final ConditionContext conditionContext, final AnnotatedTypeMetadata annotatedTypeMetadata) {
            return PropertyUtil.containPropertyPrefix(conditionContext.getEnvironment(), PREFIX)
                    ? ConditionOutcome.match() : ConditionOutcome.noMatch("Can't find ShardingSphere readwrite-splitting rule configuration in local file.");
        }
    }
    View Code

    通过反射判断

        @SneakyThrows(ReflectiveOperationException.class)
        private static Object v2(final Environment environment, final String prefix, final Class<?> targetClass) {
            Class<?> binderClass = Class.forName("org.springframework.boot.context.properties.bind.Binder");
            Method getMethod = binderClass.getDeclaredMethod("get", Environment.class);
            Method bindMethod = binderClass.getDeclaredMethod("bind", String.class, Class.class);
            Object binderObject = getMethod.invoke(null, environment);
            String prefixParam = prefix.endsWith(".") ? prefix.substring(0, prefix.length() - 1) : prefix;
            Object bindResultObject = bindMethod.invoke(binderObject, prefixParam, targetClass);
            Method resultGetMethod = bindResultObject.getClass().getDeclaredMethod("get");
            return resultGetMethod.invoke(bindResultObject);
        }

    最终通过按照转换后的配置对象构建对应的服务资源对象

    --------------------------------------------------------------------------

    注册中心目前支持zookeeper/etcd

    服务加载方式全部是基于ServiceLoader,有些是默认在源码包里加载的,比如org.apache.shardingsphere.governance.repository.zookeeper.CuratorZookeeperRepository就通过下图文件启动,也有些可以自己实现然后添加的

    加载方式

    @NoArgsConstructor(access = AccessLevel.PRIVATE)
    public final class RegistryCenterRepositoryFactory {
        
        static {
            ShardingSphereServiceLoader.register(RegistryCenterRepository.class);
        }
        
        /**
         * Create new instance of Registry center repository.
         * 
         * @param config governance configuration
         * @return new instance of Registry center repository
         */
        public static RegistryCenterRepository newInstance(final GovernanceConfiguration config) {
            RegistryCenterConfiguration registryCenterConfig = config.getRegistryCenterConfiguration();
            Preconditions.checkNotNull(registryCenterConfig, "Registry center configuration cannot be null.");
            RegistryCenterRepository result = TypedSPIRegistry.getRegisteredService(RegistryCenterRepository.class, registryCenterConfig.getType(), registryCenterConfig.getProps());
            result.init(config.getName(), registryCenterConfig);
            return result;
        }
    }

     注册中心需要实现的逻辑也很简单,看图就知道了

    整个注册中心基于临时节点跟session生命周期相同的特性实现实例和数据库的注册发现,基于监听机制实现配置变更的发现通知

    通过google eventbus事件机制传递到观察者实现配置动态化

    zk治理节点

  • 相关阅读:
    HDU
    HDU
    A. Reorder the Array
    A. New Building for SIS Codeforce
    HUD Is It A Tree?!!!!!)
    博客园申请博客批准
    一起学CC3200之CRC校验
    新安装CCS 编译问题Process_begin :createProcess
    一起学CC3200之开发环境简介(2)烧录程序
    新安装CCS 后编译出现问题:gmake:No rule to make target clean
  • 原文地址:https://www.cnblogs.com/it-worker365/p/14990876.html
Copyright © 2011-2022 走看看