分库分表学习

分库分表学习

https://articles.zsxq.com/id_xq8o4sj295df.html

AOP核心概念

可参考 JavaGuide的博客 ,具体的不在这里介绍了。

分库分表哪里体现了AOP?

数据库分库分表组件在这篇文章中已经介绍得很详细了,我们要学习的是这个组件中哪里体现出来了AOP,以及说当我们进行分库分表查询的时候,源码的调用逻辑是怎么样的。

我们要思考,在这个分库分表组件中,AOP的关键核心,在哪里体现出来了?

横切关注点(cross-cutting concerns)

横切关注点指的是多个类或对象中的公共行为(如日志记录、事务管理、权限控制、接口限流、接口幂等等)。

数据库路由逻辑是这个组件的横切关注点,包括:

  • 从方法参数中解析路由字段(getAttrValue)。
  • 根据路由字段计算目标库和表的索引(dbRouterStrategy.doRouter)。
  • 在 SQL 执行时动态修改表名(MyBatis 拦截器)。
  • 清理 ThreadLocal 中的路由信息(dbRouterStrategy.clear)。

切面(Aspect)

切面是对横切关注点进行封装的类,一个切面是一个类。切面可以定义多个通知,用来实现具体的功能。

逻辑分为两部分:

  1. 方法级别的路由逻辑:
    • 使用 @Around 注解的 doRouter 方法,将路由逻辑应用到带有 @DBRouter 注解的方法。
    • 实现动态路由的核心逻辑。
  2. SQL 级别的表名替换
    • MyBatis 拦截器中的 intercept 方法,用于拦截并修改 SQL,完成分表逻辑。

切面贯穿了方法调用和 SQL 执行两个层面。

连接点(JoinPoint)

连接点是方法调用或者方法执行时的某个特定时刻(如方法调用、异常抛出等)。

  1. 方法调用:
    • 带有 @DBRouter 注解的方法是连接点,例如 service.insertUser() 方法。
  2. SQL 执行:
    • MyBatis 拦截器中的 BoundSql 是另一个连接点,表示每次执行的 SQL 语句。

连接点提供了拦截点,切面通过切点筛选具体的连接点。

通知(Advice)

通知就是切面在某个连接点要执行的操作。通知有五种类型,分别是前置通知(Before)、后置通知(After)、返回通知(AfterReturning)、异常通知(AfterThrowing)和环绕通知(Around)。前四种通知都是在目标方法的前后执行,而环绕通知可以控制目标方法的执行过程。

在组件中的体现:

  1. 方法级通知
    • doRouter 方法中:
      • 前置逻辑:解析路由字段,计算库表索引(dbRouterStrategy.doRouter)。
      • 环绕逻辑:通过 jp.proceed() 执行业务方法。
      • 后置逻辑:清理路由信息(dbRouterStrategy.clear)。
  2. SQL 级通知
    • 在 MyBatis 拦截器中的 intercept 方法:
      • 前置逻辑:提取 SQL 表名。
      • 环绕逻辑:通过动态修改 BoundSql 替换表名。
      • 后置逻辑:恢复原始状态(如果有需要)。

切点(Pointcut)

一个切点是一个表达式,它用来匹配哪些连接点需要被切面所增强。切点可以通过注解、正则表达式、逻辑运算等方式来定义。比如 execution(* com.xyz.service..*(..))匹配 com.xyz.service 包及其子包下的类或接口。

在组件中的体现:

切点通过以下方式定义:

  1. 方法级切点

    1
    @Around("aopPoint() && @annotation(dbRouter)")
    • aopPoint() 是一个通用的切点定义(可能是包或类范围)。
    • @annotation(dbRouter) 限定只拦截带有 @DBRouter 注解的方法。
  2. SQL 级切点

    • MyBatis 插件拦截了 StatementHandler 接口的 prepare 方法,用于动态修改 SQL。

切点将通知与具体的连接点绑定,决定哪些方法或 SQL 会被拦截。

织入(Weaving)

织入是将切面和目标对象连接起来的过程,也就是将通知应用到切点匹配的连接点上。常见的织入时机有两种,分别是编译期织入(Compile-Time Weaving 如:AspectJ)和运行期织入(Runtime Weaving 如:AspectJ、Spring AOP)。

在组件中的体现:

  1. 方法级织入
    • Spring AOP 在运行时使用动态代理,将 doRouter 的切面逻辑织入到带有 @DBRouter 注解的方法中。
    • 例如,当调用 service.insertUser() 时,Spring AOP 代理会触发 doRouter 方法。
  2. SQL 级织入
    • MyBatis 拦截器在运行时动态修改 SQL 执行流程,通过反射直接修改 SQL 表名。
    • 每次执行 SQL 时,intercept 方法会被调用,动态替换表名。

织入过程确保切面逻辑能够在正确的连接点上执行。

面试题

简单技术问题:

  1. 什么是 AOP?在 DB-Router 中如何应用 AOP?

  2. AbstractRoutingDatasource 是什么?它的作用是什么?

  3. ThreadLocal是什么?在 DB-Router 中是如何使用的?

  4. 什么是哈希散列?在 DB-Router 中为什么选择了哈希散列算法?

  5. SAC 测试是什么?在 DB-Router 中如何应用 SAC测试?

中等技术问题:

  1. 什么是 MyBatis Plugin? 在 DB-Router 中如何应用 MyBatis Plugin 实现动态变更表信息?
    2.分库分表的散列算法有哪些,各自的优缺点是什么?

  2. 在 DB-Router 中如何支持个性化的分库分表控制?请结合具体实例说明。

  3. 在 DB-Router 中如何实现扩展监控、扫描、策略等规则?

  4. 什么是雪崩测试?在 DB-Router 中如何进行雪崩测试?

难度技术问题:

  1. 在 DB-Router 的架构模型中,如何实现扩展性和灵活性的平衡?

  2. 在 DB-Router 中如何保证数据路由的高效性和准确性?

  3. 在 DB-Router 中,如何避免分库分表后产生的性能问题?

  4. 在 DB-Router 中如何应对高并发的场景?请结合具体实例说明。

  5. 在 DB-Router 的设计过程中,遇到了哪些技术难点?是如何解决的?
    可合

-------------本文结束,感谢您的阅读-------------