现状
当前企业级开发中,基于数据库的binlog日志去做一些联动动作,已经是习以为常的解决方案。
而如何监听binlog日志,发送mq给其他系统,逻辑往往被封装好直供开发者直接使用。
目标
自己写代码实现监听binlog日志(发mq就不写了,之前已经有过实现)
前置
首先需要确保mysql开启了binlog播报功能:
当这里显示为ON,就代表当前库已经开启binlog播报了,我这边默认是开启的。
所谓binlog,其实就是数据库系统自己的操作日志。
代码
public class TestBin {
public static void main(String[] args) {
BinaryLogClient client = new BinaryLogClient("localhost", 3306, "root", "123456");
client.setServerId(2);
client.registerEventListener(event -> {
EventData data = event.getData();
System.out.println("data:" + data);
if (data instanceof TableMapEventData) {
System.out.println("Table:");
TableMapEventData tableMapEventData = (TableMapEventData) data;
System.out.println(tableMapEventData.getTableId() + ": [" + tableMapEventData.getDatabase() + "-" + tableMapEventData.getTable() + "]");
}
if (data instanceof UpdateRowsEventData) {
System.out.println("Update:");
System.out.println(data.toString());
} else if (data instanceof WriteRowsEventData) {
System.out.println("Insert:");
System.out.println(data.toString());
} else if (data instanceof DeleteRowsEventData) {
System.out.println("Delete:");
System.out.println(data.toString());
}
});
try {
client.connect();
} catch (IOException e) {
e.printStackTrace();
}
// Table:
//94: [gbstest-user]
//Insert:
//WriteRowsEventData{tableId=94, includedColumns={0, 1}, rows=[
// [125, eee]
//]}
//Table:
//94: [gbstest-user]
//Delete:
//DeleteRowsEventData{tableId=94, includedColumns={0, 1}, rows=[
// [123, xiaoming]
//]}
//Table:
//94: [gbstest-user]
//Update:
//UpdateRowsEventData{tableId=94, includedColumnsBeforeUpdate={0, 1}, includedColumns={0, 1}, rows=[
// {before=[124, abc], after=[126, abc]}
//]}
//Table:
//94: [gbstest-user]
//Insert:
//WriteRowsEventData{tableId=94, includedColumns={0, 1}, rows=[
// [130, eee]
//]}
//Table:
//94: [gbstest-user]
//Insert:
//WriteRowsEventData{tableId=94, includedColumns={0, 1}, rows=[
// [131, eee]
//]}
//Table:
//94: [gbstest-user]
//Insert:
//WriteRowsEventData{tableId=94, includedColumns={0, 1}, rows=[
// [132, eee]
//]}
//Table:
//94: [gbstest-user]
//Insert:
//WriteRowsEventData{tableId=94, includedColumns={0, 1}, rows=[
// [133, eee]
//]}
//Table:
//94: [gbstest-user]
//Insert:
//WriteRowsEventData{tableId=94, includedColumns={0, 1}, rows=[
// [134, eee]
//]}
}
}
核心代码其实比较短,这里把执行的部分结果也打上去了。
可以看到shyiko这款第三方框架为我们提供了很完整的 java代码连接数据库,解析binlog日志的功能
注册好监听器后,从eventData中读取你需要的内容。
而事实是读取到的eventData内容也不会太复杂(这取决你执行的sql)
这里贴出我执行的sql:
这里我测试了增删改查四种语句,其中查是不会有binlog的。
也就是binlog只有对数据有改动的操作才会播报。
代码层面也对增删改,做了区分:
这里只是简单的把binlog打印到控制台,其实后续如果要播报到mq,再做后续消费,也都是一样基于这个监听的EventData!