ShardingSphere之路由引擎

431 阅读1分钟

说明

路由引擎主要使用上下文环境中的配置,配置信息由解析引擎生成的语法树和分库分表相关信息组成。路由引擎会根据是否携带分片键等不同规则,进行不同的路由选择,如下图:

image.png

public ExecutionContext generateExecutionContext(final LogicSQL logicSQL, final ShardingSphereMetaData metaData, final ConfigurationProperties props) {
    //路由
    RouteContext routeContext = route(logicSQL, metaData, props);
    //重写
    SQLRewriteResult rewriteResult = rewrite(logicSQL, metaData, props, routeContext);
    //执行
    ExecutionContext result = createExecutionContext(logicSQL, metaData, routeContext, rewriteResult);
    //日志
    logSQL(logicSQL, props, result);
    return result;
}
private RouteContext route(final LogicSQL logicSQL, final ShardingSphereMetaData metaData, final ConfigurationProperties props) {
    //创建路由引擎,并调用路由方法
    return new SQLRouteEngine(metaData.getRuleMetaData().getRules(), props).route(logicSQL, metaData);
}
public RouteContext route(final LogicSQL logicSQL, final ShardingSphereMetaData metaData) {
    //判断sql是否需要全库执行,创建全库的路由执行器或部分的路由执行器
    SQLRouteExecutor executor = isNeedAllSchemas(logicSQL.getSqlStatementContext().getSqlStatement()) ? new AllSQLRouteExecutor() : new PartialSQLRouteExecutor(rules, props);
    //调用路由方法
    return executor.route(logicSQL, metaData);
}

全库路由类

public final class AllSQLRouteExecutor implements SQLRouteExecutor {
    
    @Override
    public RouteContext route(final LogicSQL logicSQL, final ShardingSphereMetaData metaData) {
        RouteContext result = new RouteContext();
        for (String each : metaData.getResource().getDataSources().keySet()) {
            result.getRouteUnits().add(new RouteUnit(new RouteMapper(each, each), Collections.emptyList()));
        }
        return result;
    }
}

部分路由类

public final class PartialSQLRouteExecutor implements SQLRouteExecutor {
    
    static {
        ShardingSphereServiceLoader.register(SQLRouter.class);
    }
    
    private final ConfigurationProperties props;
    
    @SuppressWarnings("rawtypes")
    private final Map<ShardingSphereRule, SQLRouter> routers;
    
    public PartialSQLRouteExecutor(final Collection<ShardingSphereRule> rules, final ConfigurationProperties props) {
        this.props = props;
        routers = OrderedSPIRegistry.getRegisteredServices(SQLRouter.class, rules);
    }
    
    @Override
    @SuppressWarnings({"unchecked", "rawtypes"})
    public RouteContext route(final LogicSQL logicSQL, final ShardingSphereMetaData metaData) {
        RouteContext result = new RouteContext();
        for (Entry<ShardingSphereRule, SQLRouter> entry : routers.entrySet()) {
            if (result.getRouteUnits().isEmpty()) {
                result = entry.getValue().createRouteContext(logicSQL, metaData, entry.getKey(), props);
            } else {
                entry.getValue().decorateRouteContext(result, logicSQL, metaData, entry.getKey(), props);
            }
        }
        if (result.getRouteUnits().isEmpty() && 1 == metaData.getResource().getDataSources().size()) {
            String singleDataSourceName = metaData.getResource().getDataSources().keySet().iterator().next();
            result.getRouteUnits().add(new RouteUnit(new RouteMapper(singleDataSourceName, singleDataSourceName), Collections.emptyList()));
        }
        return result;
    }
}