Canal 數據監控的使用

環境:
Docker: 19 版本
Java: 11 版本
MySQL: 8 版本
Canal: 1.1.+ 版本

1. MySQL 設置

1.1 開啓 binlog

修改 my.cnf 文件
正常在 /etc/mysql/my.cnf
添加下面的內容.

# binlog setting
log-bin=/root/binlog/mysql-bin
server-id=13306

在這裏插入圖片描述

注: 如果使用了共享卷需要進行授權

chmod -R 777 <mysql-bin 文件所在的主機路徑>

重啓容器

查看 binlog 的狀態

SHOW VARIABLES LIKE 'log_bin%'

在這裏插入圖片描述

binlog 有三種格式, 默認是 ROW

SHOW VARIABLES LIKE 'binlog_format'

在這裏插入圖片描述

1.2 使用 root 賬號創建用戶並授予權限

create user canal@'%' IDENTIFIED by 'canal';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT, SUPER ON *.* TO 'canal'@'%';
FLUSH PRIVILEGES;

2. Docker 安裝 canal-server

運行容器並進入

dokcer pull canal/canal-server
docker run -d -it -p 11111:11111 --name=canal canal/canal-server
docker exec -it canal /bin/bash

修改文件

vi canal-server/conf/canal.properties

在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述

vi canal-server/conf/example/instance.properties

在這裏插入圖片描述

.* 代表所有的數據庫或者表
.*\\..* 中兩個 .* 中間夾了一個 \\.\\. 是用於轉義 . 的。 第一個 .* 代表所有的數據庫 第二個 .* 代表所有的表
.*\\..* ==> 所有的數據庫.所有的表

# 重啓
docker restart canal

3. Java 實現 Canal Client

需要建立一個 SpringBoot 形成將其形成 Jar. 方便使用.
https://www.bilibili.com/video/BV1GE411G7Hg?p=93
這個視頻下面的評論中的連接就有

導包

 <dependency>
     <groupId>com.ykenan.ykenan</groupId>
     <artifactId>commerce_common</artifactId>
     <version>1.0-SNAPSHOT</version>
 </dependency>
 <!-- canal.client -->
 <!--<dependency>
     <groupId>com.alibaba.otter</groupId>
     <artifactId>canal.client</artifactId>
     <version>1.1.3</version>
 </dependency>-->
 <!-- 項目 canal.client jar 包 -->
 <dependency>
     <groupId>com.ykenan.ykenan</groupId>
     <artifactId>commerce_canal</artifactId>
     <version>0.0.1-SNAPSHOT</version>
 </dependency>

application.yml 配置文件
文件中的 example 就是上邊設置 canal.destinations 保持一致, 默認就是 example.

# canal client 配置
canal:
  client:
    instances:
      example:
        host: 192.168.19.129
        port: 11111
        userName: canal
        password: canal

啓動類 加上 @EnableCanalClient 註解

監聽類

package com.commerce.canal.listener;

import com.alibaba.otter.canal.protocol.CanalEntry;
import com.ykenan.ykenan.annotation.CanalEventListener;
import com.ykenan.ykenan.annotation.DeleteListenPoint;
import com.ykenan.ykenan.annotation.InsertListenPoint;
import com.ykenan.ykenan.annotation.UpdateListenPoint;

import java.util.List;

/**
 * 實現 MySQL 數據監聽
 */
@CanalEventListener
public class CanalDataEventListener {

    /**
     * 增加監聽
     *
     * @param eventType 當前操作的類型 (例如:增加數據)
     * @param rowData   發生變更的一行數據
     */
    @InsertListenPoint
    public void onEventInsert(CanalEntry.EventType eventType, CanalEntry.RowData rowData) {
        List<CanalEntry.Column> afterColumnsList = rowData.getAfterColumnsList();
        System.out.println("增加後的數據:");
        for (CanalEntry.Column column : afterColumnsList) {
            // 列名
            String name = column.getName();
            // 變更後的數據
            String value = column.getValue();
            System.out.println(name + ":" + value);
        }
    }



    /**
     * 修改監聽
     *
     * @param eventType 當前操作的類型 (例如:增加數據)
     * @param rowData   發生變更的一行數據
     */
    @UpdateListenPoint
    public void onEventUpdate(CanalEntry.EventType eventType, CanalEntry.RowData rowData) {
        List<CanalEntry.Column> beforeColumnsList = rowData.getBeforeColumnsList();
        System.out.println("修改前的數據:");
        for (CanalEntry.Column column : beforeColumnsList) {
            System.out.println(column.getName() + ":" + column.getValue());
        }
        System.out.println("修改後的數據:");
        List<CanalEntry.Column> afterColumnsList = rowData.getAfterColumnsList();
        for (CanalEntry.Column column : afterColumnsList) {
            System.out.println(column.getName() + ":" + column.getValue());
        }
    }

    /**
     * 刪除監聽
     *
     * @param eventType 當前操作的類型 (例如:增加數據)
     * @param rowData   發生變更的一行數據
     */
    @DeleteListenPoint
    public void onEventDelete(CanalEntry.EventType eventType, CanalEntry.RowData rowData) {
        List<CanalEntry.Column> beforeColumnsList = rowData.getBeforeColumnsList();
        System.out.println("刪除前的數據:");
        for (CanalEntry.Column column : beforeColumnsList) {
            System.out.println(column.getName() + ":" + column.getValue());
        }
    }

}

效果

在這裏插入圖片描述

監聽類中將上面的合在一個自定義中


    /**
     * 自定義監聽
     *
     * @param eventType 當前操作的類型 (例如:增加數據)
     * @param rowData   發生變更的一行數據
     */
    @ListenPoint(
            // 指定監聽的類型
            eventType = {CanalEntry.EventType.DELETE, CanalEntry.EventType.UPDATE, CanalEntry.EventType.INSERT,},
            // 指定監聽的數據庫
            schema = {"commerce_ad"},
            // 指定監聽的表
            table = {"tb_ad"},
            // 指定實例的地址
            destination = "example"
    )
    public void onEvent(CanalEntry.EventType eventType, CanalEntry.RowData rowData) {
        List<CanalEntry.Column> beforeColumnsList = rowData.getBeforeColumnsList();
        System.out.println("自定義操作前的數據:");
        for (CanalEntry.Column column : beforeColumnsList) {
            System.out.println(column.getName() + ":" + column.getValue());
        }
        System.out.println("自定義操作操作後的數據:");
        List<CanalEntry.Column> afterColumnsList = rowData.getAfterColumnsList();
        for (CanalEntry.Column column : afterColumnsList) {
            System.out.println(column.getName() + ":" + column.getValue());
        }
    }

效果是一樣的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章