Java binLog日志监听

本文介绍了如何在Windows下开启MySQL的BinLog功能,以及使用Java和Maven的mysql-binlog-connector-java库进行BinLog监听,针对不同事件类型(如table_map_event、update_rows_event等)进行处理逻辑的示例。

监听指定的表去做一些处理逻辑,首先是要开启M有SQL的配置,然后再撸代码。

一、Windows下开启MySQL binLog日志

首先要开启MySQL的BinLog 管理

show variables like '%log_bin%';

 

如果发现是OFF,打开mysql文件夹下面的my.ini,修改一下

如果不知道my.ini 在哪里,打开【服务】-> 右击属性

 

拉到最后就可以看见my.ini,然后找到文件后

[mysqld] 下面加

# 开启bin-log
log-bin=mysql-bin          # 开启binlog功能
binlog-format=ROW          # 设置binlog格式
server_id=1                # 设置服务ID号

然后 重启服务,就会发现已经起好了 

二、Java代码示例演示

首先引入Maven包

 <dependency>
     <groupId>com.github.shyiko</groupId>
     <artifactId>mysql-binlog-connector-java</artifactId>
     <version>0.21.0</version>
 </dependency>

上代码

import cn.hutool.core.collection.ListUtil;
import com.alibaba.fastjson2.JSON;
import com.github.shyiko.mysql.binlog.BinaryLogClient;
import com.github.shyiko.mysql.binlog.event.*;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.controller.websocket.AlarmWebSocket;
import com.ruoyi.web.service.IWidfireDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;
import java.util.Map;


/**
 * mysql bin log 日志监听
 */
@Component
@Slf4j
public class MySQLBinaryLogConfig {


    public static IWidfireDataService widfireDataService;

    @Autowired
    public void setSenderService(IWidfireDataService widfireDataService){
        MySQLBinaryLogConfig.widfireDataService= widfireDataService;
    }


    private static final List<String> TABLE_NAME = ListUtil.of("alart_ai"); //数据库表,需要监听的表


    {
        System.out.println("启动监听:启动中");
        getThread().start();
        System.out.println("启动监听:成功");
    }

    public Thread getThread() {
        BinaryLogClient client = new BinaryLogClient("127.0.0.1", 3306, "root", "123456");
        client.setServerId(1);
        return new Thread(() -> {
            client.registerEventListener(event -> {
                String table =null;
                final EventData data = event.getData();
                if (data instanceof TableMapEventData) {
                    TableMapEventData tableMapEventData = (TableMapEventData) data;
                    String database = tableMapEventData.getDatabase();
                    table = tableMapEventData.getTable();

                    log.info("数据表:{},data:{},database:{}",table,data.toString(),database);
                }else if (data instanceof UpdateRowsEventData) {
                    UpdateRowsEventData tableMapEventData = (UpdateRowsEventData) data;

                    System.out.println("更新:");
                } else if (data instanceof WriteRowsEventData) {
                    System.out.println("添加:");
                } else if (data instanceof DeleteRowsEventData) {
                    System.out.println("删除:");
                }

                if(StringUtils.isNotEmpty(table) && TABLE_NAME.contains(table)){
                    log.info("<<<<<< 收到MySQL binLog 日志推送 >>>>>>>");
                    //开始编写具体的逻辑
                    
                }

            });
            try {
                client.connect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

    }






}

<think>我们被要求详细说明如何使用Canal订阅MySQLBinlog。参考引用[1]和[2]的内容,我们知道Canal是一个用于增量订阅MySQLbinlog的工具,它可以将binlog的变化实时同步到其他数据存储(如Kafka)中。目标:提供使用Canal订阅MySQLBinlog的详细步骤和配置。步骤分解:1.环境准备2.MySQL配置(开启binlog并配置权限)3.Canal部署与配置4.启动Canal5.使用示例(可选,比如如何消费binlog事件)注意:引用中提到了Canal可以将数据同步到Kafka,但用户当前问题只关注如何订阅Binlog(即Canal的基本使用),因此我们重点在Canal本身的配置和使用。详细步骤:一、环境准备-安装Java(Canal运行需要Java环境,建议Java8或以上)-MySQL(需要开启binlog,且为ROW模式)-下载Canal:从官方仓库(https://github.com/alibaba/canal)下载最新版本,如canal.deployer-1.1.7.tar.gz二、MySQL配置1.开启binlog:修改MySQL配置文件(my.cnf或my.ini),添加以下配置:[mysqld]log-bin=mysql-bin#开启binlogbinlog-format=ROW#设置binlog模式为ROWserver_id=1#设置server_id,需要唯一2.创建Canal用户并授权:CREATEUSERcanalIDENTIFIEDBY'canal';GRANTSELECT,REPLICATIONSLAVE,REPLICATIONCLIENTON*.*TO'canal'@'%';FLUSHPRIVILEGES;3.重启MySQL使配置生效。三、Canal部署与配置1.解压下载的Canal安装包。2.修改Canal配置文件(位于conf目录下):-修改conf/example/instance.properties(一个instance对应一个数据源):canal.instance.master.address=127.0.0.1:3306#MySQL地址canal.instance.dbUsername=canal#用户名canal.instance.dbPassword=canal#密码canal.instance.connectionCharset=UTF-8#字符集canal.instance.filter.regex=.*\\..*#监控所有库所有表(可调整)#其他配置保持默认3.修改Canal服务端配置(conf/canal.properties):-一般默认即可,但注意canal.port(默认11111)为Canal服务端口,确保不被占用。-如果需要将数据发送到Kafka,则修改模式为kafka,并配置kafka相关参数(但用户当前问题未要求,可暂不涉及)。四、启动Canal1.进入Canal的bin目录,执行启动脚本:Linux:shstartup.shWindows:startup.bat2.查看日志(logs/canal/canal.log和logs/example/example.log)确认启动是否成功。五、使用Java客户端消费binlog事件(示例)Canal提供了简单的客户端示例,我们可以编写一个Java程序来订阅binlog事件。1.添加依赖(Maven):<dependency><groupId>com.alibaba.otter</groupId><artifactId>canal.client</artifactId><version>1.1.7</version></dependency>2.编写客户端代码:```javapublicclassCanalClientExample{publicstaticvoidmain(String[]args){//创建连接CanalConnectorconnector=CanalConnectors.newSingleConnector(newInetSocketAddress("127.0.0.1",11111),"example","","");intbatchSize=1000;try{connector.connect();connector.subscribe(".*\\..*");//订阅所有库所有表connector.rollback();//回滚到未消费的位置while(true){Messagemessage=connector.getWithoutAck(batchSize);//获取指定数量的消息longbatchId=message.getId();if(batchId!=-1&&message.getEntries().size()>0){//处理binlog事件printEntry(message.getEntries());}connector.ack(batchId);//确认消费}}finally{connector.disconnect();}}privatestaticvoidprintEntry(List<Entry>entries){for(Entryentry:entries){if(entry.getEntryType()==EntryType.TRANSACTIONBEGIN||entry.getEntryType()==EntryType.TRANSACTIONEND){continue;}RowChangerowChange;try{rowChange=RowChange.parseFrom(entry.getStoreValue());}catch(Exceptione){thrownewRuntimeException("解析错误",e);}EventTypeeventType=rowChange.getEventType();System.out.println(String.format("事件类型:%s",eventType));for(RowDatarowData:rowChange.getRowDatasList()){if(eventType==EventType.DELETE){printColumns(rowData.getBeforeColumnsList());}elseif(eventType==EventType.INSERT){printColumns(rowData.getAfterColumnsList());}else{System.out.println("------更新前------");printColumns(rowData.getBeforeColumnsList());System.out.println("------更新后------");printColumns(rowData.getAfterColumnsList());}}}}privatestaticvoidprintColumns(List<Column>columns){for(Columncolumn:columns){System.out.println(column.getName()+":"+column.getValue()+"update="+column.getUpdated());}}}```六、验证-运行上述Java程序,然后在MySQL中执行增删改操作,观察程序输出。注意事项:-Canal需要MySQL的binlog格式为ROW,否则无法正确解析。-确保网络连通,Canal服务器能够访问MySQL。-如果同步到Kafka,需要修改canal.properties中的canal.serverMode为kafka,并配置kafka相关参数。以上即为使用Canal订阅MySQLBinlog的详细步骤。生成相关问题:1.如何配置Canal将MySQLBinlog同步到Kafka?2.Canal的HA(高可用)模式如何搭建?3.如何解析Canal获取的binlog事件中的JSON字段?4.在MySQL主从架构中,Canal应该连接主库还是从库?5.Canal支持哪些消息中间件(除Kafka外)?</think>### 如何使用 Canal 订阅 MySQL Binlog:详细步骤与配置指南 #### 一、核心原理 Canal 通过模拟 MySQL Slave 的交互协议,**伪装为从库**向 Master 请求 Binlog 数据流[^1]。其核心组件: ```mermaid graph LR A[MySQL Master] -- Binlog协议 --> B(Canal Server) B -- 解析转换 --> C[EventSink] C -- 数据输出 --> D(Kafka/RocketMQ/ES等) ``` #### 二、环境准备 1. **MySQL 配置**(需重启 MySQL) ```ini # my.cnf 配置 [mysqld] server_id=1 log-bin=mysql-bin # 启用Binlog binlog_format=ROW # 必须为ROW模式[^2] binlog_row_image=FULL gtid_mode=ON # 推荐开启GTID ``` 2. **创建 Canal 专用账户** ```sql CREATE USER 'canal'@'%' IDENTIFIED BY 'canal_password'; GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%'; FLUSH PRIVILEGES; ``` #### 三、Canal 部署与配置 1. **下载与解压** ```bash wget https://github.com/alibaba/canal/releases/download/canal-1.1.7/canal.deployer-1.1.7.tar.gz tar -zxvf canal.deployer-1.1.7.tar.gz -C /opt/canal ``` 2. **修改核心配置** - **canal.properties**(服务端配置) ```properties canal.port=11111 # Canal服务端口 canal.destinations=example # 实例名称 canal.instance.global.mode=spring # 存储模式 ``` - **instance.properties**(数据源配置) ```properties canal.instance.mysql.slaveId=1234 # 唯一ID,不与集群冲突 canal.instance.master.address=127.0.0.1:3306 canal.instance.dbUsername=canal canal.instance.dbPassword=canal_password canal.instance.filter.regex=.*\\..* # 监控所有库表 ``` #### 四、启动与验证 1. **启动 Canal Server** ```bash cd /opt/canal/bin ./startup.sh # Linux startup.bat # Windows ``` 2. **检查日志** ```bash tail -f /opt/canal/logs/example/example.log # 看到如下输出表示成功: # Main : prepare to start destination [example] # Main : start successful.... ``` 3. **Binlog 位置验证** ```sql SHOW MASTER STATUS; /* 输出示例 +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000003 | 120 | | | +------------------+----------+--------------+------------------+ */ ``` #### 五、客户端消费示例(Java) ```java public class CanalClient { public static void main(String[] args) { // 1. 创建连接 CanalConnector connector = CanalConnectors.newSingleConnector( new InetSocketAddress("127.0.0.1", 11111), "example", "", "" ); try { connector.connect(); connector.subscribe(".*\\..*"); // 订阅所有表 // 2. 循环拉取Binlog事件 while (true) { Message message = connector.getWithoutAck(100); long batchId = message.getId(); for (CanalEntry.Entry entry : message.getEntries()) { if (entry.getEntryType() == CanalEntry.EntryType.ROWDATA) { // 3. 解析数据变更 CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue()); for (CanalEntry.RowData rowData : rowChange.getRowDatasList()) { System.out.println("变更类型: " + rowChange.getEventType()); System.out.println("变更数据: " + rowData.getAfterColumnsList()); } } } connector.ack(batchId); // 4. 确认消费 } } finally { connector.disconnect(); } } } ``` #### 六、常见问题排查 | **问题现象** | **解决方案** | |--------------------------|---------------------------------------------| | 连接 MySQL 失败 | 检查账户权限、防火墙、`server_id` 唯一性[^2] | | 解析 Binlog 乱码 | 确保 MySQL 和 Canal 字符集统一为 UTF-8 | | 消费延迟高 | 调整 `canal.instance.network.receiveBufferSize` | | 内存溢出(OOM) | 限制 `canal.instance.memory.batch.mode` 大小 | #### 七、生产环境建议 1. **高可用方案** - 部署多个 Canal 实例 + ZooKeeper 选主 - MySQL 开启 GTID 模式保证断点续传[^2] 2. **性能优化** ```properties canal.instance.parser.parallel=true # 启用并行解析 canal.instance.parser.parallelThreads=8 # 线程数=CPU核数*2 ``` 3. **安全加固** - 启用 TLS 加密 Binlog 传输 - 限制 Canal 账户权限为最小集 --- ### 相关问题 1. 如何将 Canal 解析的 Binlog 数据实时写入 Kafka? 2. Canal 在 MySQL 主从切换场景下如何保证数据一致性? 3. 如何通过 Prometheus 监控 Canal 的同步延迟和吞吐量? 4. Binlog 的 ROW/MIXED/STATEMENT 模式对 Canal 解析有何影响? 5. 当 MySQL 表结构变更(ALTER)时,Canal 如何自动适配? [^1]: Canal 核心原理与 MySQL 集成配置 [^2]: Binlog 协议解析与故障处理方案
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值