qinfengge

qinfengge

醉后不知天在水,满船清梦压星河
github
email
telegram

使用canal監控資料庫

什麼是 canal#

canal,譯意為水道 / 管道 / 溝渠,主要用途是基於 MySQL 資料庫增量日誌解析,提供 增量資料訂閱和消費。

通常情況下,canal 用來同步或監控 MySQL 資料庫的資料,比如資料入庫後同步到 ES
canal 將自己偽裝成 MySQL 的從機,解析並處理主機發送的 binary log 日誌

image

配置 canal#

在使用 canal 之前,你需要配置本地的 MySQL 服務,使其啟用 binlog 日誌
window 找到安裝 MySQL 目錄下的 my.ini 文件,把下面的配置加入到 [mysqld]

#binlog文件名
log-bin=mysql-bin
#選擇row模式
binlog_format=ROW
#mysql實例id,不能和canal的slaveId重複
server_id=1

Linux 可直接修改

vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin # 開啟binlog
binlog-format=ROW # 選擇ROW模式
server_id=1 # 配置MySQL replaction需要定義,不和Canal的slaveId重複即可

配置完成後重啟 MySQL 服務
使用以下命令查看是否啟用成功

show variables like 'log_bin';

image

然後在官方倉庫下載最新版並解壓
修改 conf 文件夾下的 canal.properties 不修改使用默認也行
其中重要的是

# 指定接口
canal.port = 11111
# 指定實例
canal.destinations = example
# 指定模式,默認tcp,其它有kafka, rocketMQ, rabbitMQ, pulsarMQ
canal.serverMode = tcp
# 指定rabbitmq,不配置使用默認tcp也行
rabbitmq.host =
rabbitmq.virtual.host =
rabbitmq.exchange =
rabbitmq.username =
rabbitmq.password =
rabbitmq.deliveryMode =

然後修改 example (對應上面的實例配置) 下的 instance.properties

# 主機地址
canal.instance.master.address=127.0.0.1:3306
# 連接主機的賬戶名密碼
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
# 指定連接時的編碼
canal.instance.connectionCharset = UTF-8
# 指定監聽的資料庫與表,此配置代表監聽test庫下的全部表
canal.instance.filter.regex=test..*

配置完成後在 bin 目錄下使用 startup.bat 啟動 canal

image
此時就代表啟動成功了

spring boot 配置#

在 spring boot 中使用 canal 有以下幾種方式

  1. 使用官方依賴
  2. 使用第三方
倉庫版本優劣
https://github.com/alibaba/canal官方配置簡單,實現困難
https://github.com/NormanGyllenhaal/canal-client第三方簡單易用,斷更,有 BUG
https://github.com/behappy-project/behappy-canal第三方上面的改版,持續更新,缺點僅支持 jdk17+
https://github.com/xizixuejie/canal-spring第三方簡單易用,持續更新

推薦使用最後一個

在 maven 中添加依賴

<dependency>
    <groupId>io.github.xizixuejie</groupId>
    <artifactId>canal-spring-boot-starter</artifactId>
    <version>0.0.5</version>
</dependency>

在配置文件中註冊

# canal服務地址
canal.server=127.0.0.1:11111
# canal的集群名字,要與安裝canal時設置的名稱一致
canal.destination=example
# 未配置也使用默認的tcp模式,但未配置可能會無法監聽到,因此推薦配置
canal.server-mode=tcp

完成後在啟動類增加

@EnableCanalListener(basePackages = "com.jkkj.config.canal")

開啟監聽器,並指定監聽器的配置路徑
然後配置監聽器

@CanalListener(schemaName = "test", tableName = "testTable")
public class TestListener implements EntryListener<TestEntity> {

    private static final Logger log = LoggerFactory.getLogger(TestListener.class);

    @Override
    public void insert(TestEntity testEntity) {
        log.info("insert={}", testEntity);
    }

    @Override
    public void update(TestEntity before, TestEntity after) {
        log.info("update before={}", before);
        log.info("update after={}", after);
    }

    @Override
    public void delete(TestEntity testEntity) {
        log.info("delete={}", testEntity);
    }
}

可以使用 @CanalListener 指定庫名及表名

@CanalListener(schemaName = "test", tableName = "testTable")

也可以不指定,則會根據 Entity 對象監聽,這種方式需要在實體類中指定

@TableName(value = "inspection_result_home")

會根據這個 mybatisplus 註解實體類名自動轉換表名

擴展#

在使用過程中,發現如果實體類中字段為下面的情況則會報錯

image

這是因為在轉換過程中沒有指定解析器
你可以查看我提的這個 Issues,或等待作者修改 (作者已修改)

docker 安裝#

在 Linux 下使用 docker 安裝是比較簡單的

  1. 下載鏡像
docker pull canal/canal-server:v1.1.5
  1. 先啟動一次
docker run -p 11111:11111 --name canal -d canal/canal-server:v1.1.5
  1. 複製配置文件
# 拷貝配置文件
docker cp canal:/home/admin/canal-server/conf/example/instance.properties /home/docker/canal/conf
docker cp canal:/home/admin/canal-server/conf/canal.properties /home/docker/canal/conf

前面為容器內地址,後面的 /home/jk/docker/canal/conf 是宿主機地址
4. 修改配置文件
主要修改的地方為 instance.properties 下的

# 主機地址
canal.instance.master.address=127.0.0.1:3306

127.0.0.1 指代的是容器地址,如果你的 MySQL 安裝在宿主機內,則需要指定宿主機的資料庫地址。使用 ifconfig 命令查看 docker0 就表示宿主機地址

image

  1. 重啟鏡像
docker stop canal
docker rm canal
docker run -p 11111:11111 --name canal \
-v /home/jk/docker/canal/conf/instance.properties:/home/admin/canal-server/conf/example/instance.properties \
-v /home/jk/docker/canal/conf/canal.properties:/home/admin/canal-server/conf/canal.properties \
-d canal/canal-server:v1.1.5

不使用最新版本 canal 鏡像的原因可查看此鏈接

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。