基于数据库Binlog记录操作日志-实践篇

前言

  1. 本篇要实现的功能
    1.1 cannal监听指定的表
    1.2 切面写入操作信息,通过traceId进行关联
    1.3 MQ消费消息,将diff日志记录到指定的traceId记录中

Cannal的过滤(只监听指定的表)

简单介绍Cannal启动流程

在这里插入图片描述

  1. 如果启动模式为spring(mode或者globalConfig.mode),则读取设置配置文件,调用SpringCanalInstanceGenerator#generate去生成实例
    	canal.instance.global.spring.xml = classpath:spring/file-instance.xml
    

过滤机制初始化

  1. 解析过滤处理(spring/file-instance.xml)
    1.1 读取exmaple/instance.properties的canal.instance.filter.regex属性,没有则默认为.
    1.2 解析完后,调用AbstractMysqlEventParser#setEventFilter设置eventFilter属性
    在这里插入图片描述

AviaterRegexFilter#filter过滤

在这里插入图片描述

  1. 在LogEventConvert#parseRowsEventForTableMeta进行过滤拦截
    1.1 调式发现fullname为test.user(数据库.表名),所以可以修改正则表达式只监听满足指定表
    在这里插入图片描述

TraceId的设计

  1. 通过TraceId关联操作信息和数据变更信息,但TraceId怎么传递了?
    1.1 TraceId在切面入口生成,然后存到调用链上下文
    1.2 在JDBC数据库操作时,更新业务表的TraceId字段
    1.3 Cannal监听时取出变更后的TraceId字段,与操作信息进行绑定
  2. 为了解决跨线程池的问题,使用阿里开源的ThreadLocal组件:transmittable-thread-local
    2.1 更多关于调用链上下文传递参考:http://college.creditease.cn/detail/221

TraceId传递

  1. 在切面开始处,通过日志上下文设置TraceID
  2. 在JDBC数据库操作时,取出TraceID
    public class OperationLogContext {
        final static TransmittableThreadLocal<String> ttlContext = new TransmittableThreadLocal<>();
    
        public static void setTraceId(String traceId){
            ttlContext.set(traceId);
        }
    
        public static String getTraceId(){
            return ttlContext.get();
        }
    
        public static void clear(){
            ttlContext.remove();
        }
    }
    

删除操作的特殊处理

  1. 因为删除操作,不会将traceId更新到业务表中,所以需要特殊处理
  2. 因为是通过traceId进行关联,所以在删除之前先做一次更新traceId字段,监听时只改traceId时不记录变更

TraceID的生成

  1. traceId要保证唯一性,每次操作都拥有唯一的TraceId
  2. 参考sky-walking的traceId生成
    2.1 TraceIdGenerator生成规则:2位version号 + 1位时间戳(毫秒数) + 1位进程随机号(UUID后7位) + 1位进程数号 + 1位线程号 + 1位线程内序号

总结

  1. 写到这里时,基本要实现的效果已经出来了
    在这里插入图片描述
  2. 后续会对一些细节进行完善
    2.1 在引入TTL时,尽量避免修改代码,考虑通过JavaAgent方式
    2.2 diff日志里面包含的是字段名称,将字段名称转移成可读的中文名称
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值