但基于DAL层次的解决方案对现有网站的应用来说, 冲击性太大,所以, 这虽然是个方向,但短期内无法有效施行.
4.3. 特定国际站场景的解决方案
考虑到工期以及兼容性等因素, 我们可以考虑介于JDBC API层次的解决方案和DAL层次的解决方案之间的一种解决方案.
B2B内部数据访问全部采用iBatis进行, 为了提高开发效率,自然也采用了Spring提供的SqlMapClientTemplate进行数据访问逻辑的开发. 要较少的侵入现有应用, 我们可以考虑对SqlMapClientTemplate做手脚, 既然所有的数据访问都通过该类走,那么就在该类中插入路由逻辑, 根据数据访问请求的属性指定路由规则, 然后将符合路由规则的数据访问请求路由到相应的shard上去.
这实际上就是我们现在第一阶段采用的解决方案.
Chapter 5. Cobar Client参考文档(Cobar Client Reference Documentation) 5.1. 鸟瞰Cobar Client现有架构实现 5.2. CobarSqlMapClientTemplate详解
5.2.1. 多数据源依赖管理(Multiple DataSources Management)
5.2.2. 数据访问请求路由(Routing In CobarSqlMapClientTemplate) 5.2.3. SqlAuditing
5.2.4. 其它配置与特性解释(Other Configuration or Features Explained) 5.3. MultipleDataSourcesTransactionManager详解
5.3.1. MultipleDataSourcesTransactionManager依赖的多数据源管理 5.1. 鸟瞰Cobar Client现有架构实现
CobarClient现有方案的架构如下图所示:
架构中主要侧重解决两个方面的问题:
数据访问请求的路由. 通过扩展Spring提供的SqlMapClientTemplate来切入进行扩展, 我们提供了自定义的CobarSqlMapClientTemplate, 并结合相应的Router支持来实现数据访问请求的路由功能, 并且尽量保持现有应用代码的兼容. 应用的迁移工作基本上只要替换注入的SqlMapClientTemplate实现类即可.
多数据源访问过程中的事务管理. 因为两阶段提交的分布式事务会严重影响应用的性能, 所以, 根据网站方需求,我们退而求其次, 采用Best Effort 1PC Pattern的事务策略, 提供了基于该Pattern的一个事务管理器实现MultipleDataSourcesTransactionManager, 该事务管理器扩展自Spring的AbstractPlatformTransactionManager, 应用程序迁移的时候只需要替换使用的事务管理器实现类即可.该事务管理器实现最大程度上保证事务管理的性能损失与数据一致性之间的一个合理权衡.
另外, 我们也通过AOP实现了数据源之间的HA,以及延迟加载数据库连接以保证资源的有效使用等功能, 这些在以上架构图中都有所体现.
鉴于CobarClient的两个主要关注点, 我们将对这两个关注点对于的主要组件进行详细的说明, 下面是详细内容, 各位看官上眼了...
5.2. CobarSqlMapClientTemplate详解
CobarSqlMapClientTemplate扩展了Spring的SqlMapClientTemplate, 主要在
SqlMapClientTemplate的基础之上添加了数据访问请求的路由功能, 以便应用程序可以透明的访问数据库切分后的各个数据库节点. 除此之外, CobarSqlMapClientTemplate也提供了一些附加的功能, 以方便应用的监控和使用. 下面我们分部分阐述CobarSqlMapClientTemplate的相关功能.
5.2.1. 多数据源依赖管理(Multiple DataSources Management)
在没有进行数据库切分之前, 应用程序使用Spring的SqlMapClientTemplate进行数据访问只需要为其提供单一的数据源引用, 类似于:
public interface ICobarDataSourceService { Map
com.alibaba.cobar.client.datasources.DefaultCobarDataSourceService, 通过
DefaultCobarDataSourceService, 我们可以集中管理各个数据源, 并将他们注入给CobarSqlMapClientTemplate使用. 常见的CobarSqlMapClientTemplate和其ICobarDataSourceService依赖的配置情况如下所示:
class=\ class=\ class=\ com.alibaba.cobar.client.datasources.DefaultCobarDataSourceService的配置, 我们需要通过 “dataSourceDescriptors ” 属性, 为其注入一组 com.alibaba.cobar.client.datasources.CobarDataSourceDescriptor, CobarDataSourceDescriptor主要负责对相应的数据源进行描述, 其主要配置信息包括: identity. 数据分区的唯一标志, 该标志不可与其它数据分区的标志冲突, 在定义路由规则的时候, 数据分区标志将成为路由规则的一部分. targetDataSource. 主要目标数据源的依赖引用, 通常意义上, 应用启动的时候该数据源必须是Active的. targetDetectorDataSource. 主要目标数据源伴随的HA探测用数据源, 主要用于检测主要目标数据源的状态, 通常指向与主要目标数据源相同的目标数据库, 但数据库连接池要单独配置, 以防止相互干扰.(以上配置中引用了同一个数据源引用, 只是为了演示的方便) standbyDataSource. 与主要目标数据源并列的备用数据源, 当主要目标数据源出现问题之后, 如果启用了CobarClient的HA功能支持, CobarClient将自动将数据访问切换到该备用数据源上. standbyDetectorDataSource. 备用数据源对应的HA探测用数据源, 存在的目的参见targetDetectorDataSource的说明. poolSize. CobarSqlMapClientTemplate需要根据每个目标数据源的数据库连接的数量来创建相应的线程池以便提高并发处理性能, poolSize可以帮助CobarSqlMapClientTemplate决定创建的线程池的大小,如果配置的时候该项不做配置的话, 默认情况下将以CPU内核的数量乘以5作为默认大小. Note 因为当前网站的数据源配置都是通过JNDI进行, CobarClient无法统一取得数据库连接等相关信息, 也就无法根据同一份配置信息自行创建相应的数据库连接池, 所以, 只好需要应用程序方针对每一个目标数据源再多配置一个用于HA状态探测用的数据源引用. 配置实例中使用了C3P0作为容器内的数据源定义, 但CobarClient只依赖标准的DataSource接口, 所以并不止限于C3P0数据源类型, JNDI查找的数据源或者DBCP, 甚至自己实现的DataSource都是可以的. 当前CobarDataSourceDescriptor之所以需要这些信息是因为现在网站最主要的数据库部署结构是HA双机热备的水平切分数据库集群, 但后期如果有其它的数据库部署结构, CobarDataSourceDescriptor也可能随着数据库部署结构的调整而调整. Tip 如果不需要HA双机热备支持, 那么可以让standby(.*)DataSource指向target(.*)DataSource相同的数据源应用, 或者如果DefaultCobarDataSourceService的haDataSourceCreator没有指定的话, standbyDataSource,standbyDetectorDataSource和targetDetectorDataSource可以完全不配置. CobarDataSourceDescriptor引用的数据源可以来自JNDI绑定的数据源, 也可以来自容器内定义的数据源(如上配置所示, 为了测试,我们使用了Spring容器内定义的C3P0数据源), 甚至其它形式提供的数据源, 只要为其提供标准的JDBC API中的DataSource接口实现即可. DefaultCobarDataSourceService除了依赖一组CobarDataSourceDescriptor, 它还依赖于相应的IHADataSourceCreator来进行数据库的HA支持, 如果没有提供相应的IHADataSourceCreator实现类, DefaultCobarDataSourceService默认会使用 NonHADataSourceCreator, 即不创建支持HA的数据源. CobarClient默认提供了FailoverHotSwapDataSourceCreator以支持HA, 应用方可以根据情况提供自己的IHADataSourceCreator实现来满足特定场景需要. 5.2.1.1. Cobar Client中的HA支持(HA Support In Cobar Client) CobarClient支持基于双机热备的Failover, 该功能支持抽象为IHADataSourceCreator定义: public interface IHADataSourceCreator { DataSource createHADataSource(CobarDataSourceDescriptor descriptor) throws Exception; } 前面我们说过, DefaultCobarDataSourceService在构建最终使用的数据源的时候, 通过某个IHADataSourceCreator来构建支持热切换的数据源实例. 最常见的IHADataSourceCreator实现类有 com.alibaba.cobar.client.datasources.ha.NonHADataSourceCreator和 com.alibaba.cobar.client.datasources.ha.FailoverHotSwapDataSourceCreator, 其中, NonHADataSourceCreator更多用于测试环境或者HA支持不需要CobarClient端支持的情况(比如,数据库部署层面支持HA之后, CobarClient端的HA可以不需要),所以, 如果使用CobarClient提供的HA支持, 更多的是指依赖引用FailoverHotSwapDataSourceCreator. FailoverHotSwapDataSourceCreator支持基于主动探测形式的HA以及基于被动检测形式的HA, 这两种行为可以通过属性 “passiveFailoverEnable ” 和 “positiveFailoverEnable ” 来管理启用或者禁用, 其中, 基于主动探测形式的HA默认情况下是开启的, 而基于被动探测形式的HA是禁用的, 因为基于原来的Cobar(Server版)的现有经验, 每次取得数据库连接之后都进行状态检查会损耗性能. 要启用基于主动探测形式的HA支持, Cobar Client将Cobar(Server版)的HA方式适配借用过来, 需要你在数据库中配置相应的探测表, 并配置相应的探测用SQL. 例如, 假设数据库中建立了名为cobarha的状态探测表, 那我们可以设置如下的探测用SQL: